Instructions to use neoyipeng/FinSentQwen-14B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use neoyipeng/FinSentQwen-14B with PEFT:
from peft import PeftModel from transformers import AutoModelForSequenceClassification base_model = AutoModelForSequenceClassification.from_pretrained("Qwen/Qwen3-14B") model = PeftModel.from_pretrained(base_model, "neoyipeng/FinSentQwen-14B") - Notebooks
- Google Colab
- Kaggle
FinSentQwen-14B
Two sizes. This 14B is the stronger model on the four aspects, by 0.021 (within noise). On overall sentiment the two sizes are level. FinSentQwen-4B costs about a third as much to run.
FinSentQwen-14B reads an English news passage and a named company, and labels how the passage bears on that company. Each label is positive, negative or no signal, and there are five of them, all from one forward pass:
| Aspect | What it covers |
|---|---|
| financial performance | revenue, profit, losses, results |
| demand and commercial traction | customers, orders, sales, market share |
| operations, supply, and capacity | production, supply chain, outages, expansion |
| outlook and expectations | guidance, forecasts, expected developments |
| overall company sentiment | the passage's net stance on the company |
This repository holds a LoRA adapter plus a 3-class score head for Qwen/Qwen3-14B
(revision 40c069824f4251a91eefaf281ebe4c544efd3e18), predict.py, and thresholds.json (labels and input settings). It was trained only on open-licence
news, with labels from GPT-6.1. Both FinSentQwen sizes use the same data and recipe.
Results
Scored on a sealed test of 400 news passages (2022β2024; VOA, Global Voices, 360info, Factly, Freedom of the Press Foundation) that was never used for training. The answer key is GPT-6.1, the same labeller and prompt as the training data, so the score shows how well the model learned its teacher (26 passages GPT-6.1 declined count as "no signal"). Claude Opus also labelled the test, twice and double-blind, as an independent check. Macro-F1 over the three classes, with labels by majority vote (see Decision rule):
| Task | FinSentQwen-14B | FinSentQwen-4B | Claude Opus labels |
|---|---|---|---|
| Four aspects (1,600 cells) | 0.837 | 0.816 | 0.851 |
| Overall company sentiment (400) | 0.806 | 0.810 | 0.803 |
Against the Opus labels instead:
| Task | FinSentQwen-14B | FinSentQwen-4B | GPT-6.1 labels | Opus ceiling |
|---|---|---|---|---|
| Four aspects | 0.829 | 0.818 | 0.851 | 0.960 |
| Overall company sentiment | 0.773 | 0.769 | 0.803 | 0.936 |
The Opus ceiling is the second Opus labelling scored against the first. Opus calls "no signal" on overall sentiment more often than GPT-6.1 does, which is most of the drop on that row.
- 14B vs 4B (GPT-6.1 key): the 14B is ahead by 0.021 on aspects (paired bootstrap over passages, 95% CI β0.015 to +0.059) and behind by 0.004 on overall sentiment (CI β0.033 to +0.024). That is one training seed each.
- 88% of aspect cells in the key are "no signal". The model calls 178 cells positive or negative, against 185 in the key. Per-class F1: positive 0.76, negative 0.78, no signal 0.97.
- These scores are from a later look. See How the rule was chosen below.
By source (GPT-6.1 key):
| Slice | Aspects | Overall |
|---|---|---|
| VOA (251 passages) | 0.862 | 0.839 |
| Common Pile publishers (132) | 0.776 | 0.746 |
| 2022 top-up (17) | 0.897 | 0.800 |
The 2022 slice is too small to read.
Calibration (raw softmax against the GPT-6.1 key, 10 equal-mass bins): classwise ECE 0.007 on aspects and 0.048 on overall sentiment.
Cost: fit 4.3 h on 2ΓT4. Inference is about 843 T4-seconds per 1,000 passages (β $0.08 at $0.35/T4-hour).
Use
pip install torch transformers peft bitsandbytes accelerate
python predict.py input.jsonl > output.jsonl
Each input line is {"id": ..., "company": "...", "text": "..."}. Each output line adds every aspect's label and its
probs (positive, negative, no signal). The base model loads in 4-bit NF4, as it was trained, on one CUDA GPU with
about 12 GB. predict.py reproduces the scored test predictions from this adapter.
Input format. The model sees Company: {company}\n\nPassage:\n{text}, then
\n\nAspect: {aspect}\nSignal: for each of the five aspects. The head reads the last token of each aspect line. Input
is capped at 1,024 tokens, and only the passage is cut.
Decision rule. Each cell gets the class with the largest softmax share, a plain majority vote. Nothing is tuned
or corrected, and probs is the raw softmax. thresholds.json holds the classes, aspect strings and input settings.
How the rule was chosen. The test was first scored once against the Opus labels, with a "no signal" threshold tuned on a news dev set and frozen beforehand: t 0.09 for aspects and 0.15 for overall, scoring 0.734 / 0.835. That threshold did not transfer to the test. On 2026-11-05 we switched to the plain vote, because it has nothing to tune, and made GPT-6.1 the answer key, so the model is graded by the labeller it was trained on. A prior correction toward Opus's label mix was tried in between and dropped for simplicity: it scores 0.838 / 0.811 against Opus but 0.817 / 0.810 against GPT-6.1. All of this came after the first result was known, so read the scores as less clean than a fresh test. A new sealed test is planned.
Training
- Data: 5,134 English news passages, each with a named company, and 25,670 labels (5 per passage) from GPT-6.1
(
gpt-6.1-solvia Codex). The labels and the text are in neoyipeng/FinSentQwen-data. No SEC filings or press-release exhibits were used anywhere. - Recipe: QLoRA (NF4, r 16, alpha 32, dropout 0.05, all attention and MLP projections) plus a 3-class score head; lr 1e-4, linear warmup, 2 epochs, effective batch 16 passages, fp16, 2ΓT4.
- Choosing size and epochs: a scaling grid (Qwen3 0.6B / 4B / 14B Γ three data sizes Γ 3 seeds), scored on a 1,000-passage dev holdout, picked 14B at 2 epochs under a rule fixed before the grid ran. 14B led 4B by 0.013 on aspects and 0.007 on overall sentiment there. A second epoch helped; a third did not.
- One seed is published, and it is the one that was scored.
Sources and licences
The training and test text comes from these sources. Passages are excerpted and normalized.
| Source | Licence | Link |
|---|---|---|
| Voice of America | Public domain (VOA-produced) | https://www.voanews.com/p/5338.html |
| Multilingual Open Text v1.11 (BLT Lab), VOA collection | CC BY 4.0 | https://github.com/bltlab/mot |
| Global Voices (via Common Pile) | CC BY 3.0 | https://globalvoices.org |
| 360info (via Common Pile) | CC BY 4.0 | https://360info.org |
| Factly (via Common Pile) | CC BY 4.0 | https://factly.in |
| Freedom of the Press Foundation (via Common Pile) | CC BY 4.0 | https://freedom.press |
| Balkan Diskurs (via Common Pile) | CC BY 3.0 | https://www.balkandiskurs.com |
Per-passage attribution (author, title, URL, licence) is in the dataset. The adapter is released under Apache-2.0, as is the Qwen3 base model.
Limitations
- English news only, with a company named for the passage. It is not tested on filings, social media, transcripts or other languages.
- The labels are silver: GPT-6.1 for training and the main test key, Claude Opus as a check. The two agree at 0.851 / 0.803 on the test.
- It doesn't read prices or market reaction, and it isn't investment advice.
- Downloads last month
- 23