Tripwire-AdverseMedia-4B

A LoRA adapter that turns Qwen3.5-4B into a decision model for adverse news about companies: given a news passage and a company it is monitoring, it answers typed questions (is this really about that company, is the news negative, how severe, which kind of problem, is it current) with a probability for every option. It reads; it does not write. Each answer comes from one forward pass, with no generated text, so it is fast, cheap and easy to put thresholds on, and it runs on your own GPU.

Built on Qwen3.5-4B (Apache-2.0). This is a fine-tune, not a new foundation model.

What it answers

The question set (questions.json, 18 questions) covers:

Question Type Options
same_entity: does the name in the article refer to the monitored company or person? choice same / product mention only / different / cannot tell
direction: is the news negative, neutral or positive for it? choice negative / neutral / positive
severity: how severe for its credit standing? score 0-4 no signal, early sign, material pressure, acute stress, default event
credit_relevant: could it affect revenue, cash, funding or repayment? yes / no
adverse_finding: is an allegation, investigation, penalty or ruling reported against it? yes / no
current_development: is this recent news (not commentary or a look back)? yes / no
cat_*: twelve categories (liquidity, financing, restructuring, operations, dependency, governance, legal, group, external shock, financial crime, ESG, positive) yes / no each

You can change the wording or add questions: the format accepts any yes/no, choice or score question, though answers far from the training questions are less reliable.

Quick start

pip install torch "transformers>=5.19" "peft>=0.21" accelerate
git clone https://github.com/govindshukl/tripwire.git && cd tripwire
from tripwire import Tripwire, load_questions

tw = Tripwire(adapter="govindshukl/Tripwire-AdverseMedia-4B")
state = {"target": {"name": "Halvorsen Marine ASA", "type": "company", "sector": "Shipping",
                    "description": "Norwegian operator of offshore supply vessels.",
                    "why_tracked": "Monitored company"},
         "article": {"headline": "Halvorsen Marine misses bond coupon, hires restructuring adviser",
                     "passage": "Halvorsen Marine ASA did not pay the coupon due on its 2027 bonds ..."}}
answers = tw.decide(state, load_questions(mention="Halvorsen Marine"))
print(tw.adverse(answers))     # {"adverse": True, "p_same": ..., "severity": ..., "categories": [...]}

decide reads the passage once and answers all questions as one batch. adverse is an example rule (about the company, negative, expected severity at least 0.5); set your own thresholds.

Prompt format (if you call the model directly): the state as indented JSON, then QUESTION:, the question with lettered options, and the start of the assistant turn with an empty thinking block; the answer is the softmax over the option tokens at the next position. tripwire/prompt.py in the code repository is the reference implementation.

Results

Human-labelled public sets only. Same questions, prompts and decision rule for every model; one training run; evaluated by the author.

Credit events (needle, MIT, 1,102 headlines; 173 unique defaults and downgrades, 177 upgrades and refinancings):

Model Defaults and downgrades read as adverse Upgrades and refinancings wrongly flagged
Tripwire-AdverseMedia-4B 171 / 173 (the other 2 are companies emerging from Chapter 11) 0 / 177
Qwen3.5-4B (base, same prompts) 171 / 173 0 / 177
Liquid d1-3B (base) 151 / 173 0 / 177
Vega-U 4B (zero-shot) 169 / 173 11 / 177

Company-name matching (OpenSanctions pairs, CC BY-NC 4.0, human-judged same / different company; 565 pairs, leaving out 35 that also occur in training):

Model Precision at 0.5 Recall at 0.5 Left unsure (0.3-0.7) Brier Calibration error
Tripwire-AdverseMedia-4B 0.878 0.957 1.8% 0.075 0.036
Qwen3.5-4B (base) 0.668 0.978 24.6% 0.182 0.225
Liquid d1-3B (base) 0.825 0.917 23.0% 0.117 0.102
Vega-U 4B (zero-shot) 0.799 0.885 66.9% 0.163 0.188

Reading the tables: on clear credit-event headlines the base model already does well; the fine-tune adds precise name matching, far better calibrated probabilities, and the full question set (categories, timing, adverse findings) that the base model answers poorly (it says "unsure" on a quarter of name pairs).

Speed: on one A100 (40 GB), a passage with 18 questions takes 262 ms with tree reading (14.6 ms per question), against 1,524 ms when each question re-reads the passage; on 13,770 test answers the two give the same answer 13,763 times. Linear-attention convolution ran on the PyTorch fallback; fast kernels and a serving engine (vLLM) should be faster.

Training

LoRA, rank 16 (alpha 32, dropout 0.05) on the language model's attention, linear-attention and MLP projections (vision encoder untouched); one epoch over 15,832 examples, learning rate 2e-4 with cosine decay, effective batch 16, loss on the single answer token, option order shuffled per example. Training data:

  • News passages about 30 large, news-heavy companies and related people (published news, 2024-2026), labelled by a commercial decision-model API (TypeSafe Jev) as the teacher; only answers the teacher was at least 70% sure of were used. The passages are not redistributed.
  • 1,000 human-judged company-name pairs from OpenSanctions (CC BY-NC 4.0), none of them in the evaluation pairs above apart from the 35 left out.
  • About 1,000 fictional passages written with Claude (Anthropic) to cover hard cases: namesakes, product mentions, old news, dismissed claims and victims, every category, rating actions, sovereign and credit-derivatives events, distressed exchanges and routine financings. Fictional companies only.

No evaluation headline was used or imitated in training.

Intended use and limits

Use it to triage news about companies you monitor: it suggests which items deserve a person's attention and why. Pair it with your own thresholds and a review step.

Do not use it to make automated decisions about people (credit, employment, screening); decisions about natural persons need human judgement and carry legal duties (for example under the EU AI Act and data-protection law).

Limits:

  • It can confuse companies or people with similar names; treat answers as leads, not findings.
  • English text; translated passages work but were not tested separately.
  • It reads what the passage says. It does not check facts, and it can be misled by wrong or hostile text.
  • It is stricter than its teacher on low-severity items (opinion pieces, passing product mentions); if you need maximum sensitivity, lower the thresholds and route borderline answers to review.
  • Probabilities are not calibrated beyond training; fit a temperature on your own labelled data.
  • One training run; results are the author's own evaluation.

Licence and attribution

Apache-2.0 for the adapter and code (LICENSE). The base model, Qwen3.5-4B, is Apache-2.0 by the Qwen team. Training used data from OpenSanctions (CC BY-NC 4.0, attribution: OpenSanctions, opensanctions.org). See NOTICE.

Downloads last month
42
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for govindshukl/Tripwire-AdverseMedia-4B

Finetuned
Qwen/Qwen3.5-4B
Adapter
(1,091)
this model