CoolFace
Modelpublic

Fernandosr85/fatobr-cvm-entity-scoped-adapter

sourceHugging Facellama4updated 3mo agoView on Hugging Face
0likes
Model Card

banner

FatoBR Evidence Guard — CVM Entity-Scoped Filing Adapter

LoRA adapter for entity-scoped classification of Brazilian regulatory filings, fine-tuned on Llama-4-Scout-17B-16E-Instruct via Adaption's AutoScientist platform.

Given a filing (a CVM Fato Relevante or Comunicado ao Mercado) and a named target entity, the adapter emits four independent labels — EVENT, STATUS, SCOPE, SIGNAL — each drawn from a fixed vocabulary. The SCOPE field is the point of the task: it forces the model to classify with respect to the tagged entity, distinguishing an event about the target from an event about another company named in the same document.


Task

This is closed-label classification, not open generation. Each field has a fixed set of values; anything outside them is a label hallucination.

FieldValues
EVENTEARNINGS, DIVIDEND, BUYBACK, MERGERACQUISITION, CAPITALRAISE, DEBT, REGULATORY, LEGAL, OPERATIONAL, MANAGEMENT, RESTRUCTURING, OTHER
STATUSCONFIRMED, COMPLETED, PENDINGAPPROVAL, UNDERNEGOTIATION, RUMOR, DENIED, CANCELLED
SCOPETARGETENTITY, OTHERENTITY, SECTOR, MARKET_WIDE
SIGNALPOSITIVE, NEGATIVE, NEUTRAL, MIXED, UNCERTAIN

Output format is four lines, one value each, no explanation:

EVENT=<value>
STATUS=<value>
SCOPE=<value>
SIGNAL=<value>

Usage

This is a LoRA adapter. Load it on top of the base model with PEFT. The prompt at inference must match the training template — a differently-formatted prompt degrades results on the same task.

python
import torch
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer

base = "meta-llama/Llama-4-Scout-17B-16E-Instruct"
tokenizer = AutoTokenizer.from_pretrained(base)
base_model = AutoModelForCausalLM.from_pretrained(
    base, torch_dtype=torch.float16, device_map="auto",
)
model = PeftModel.from_pretrained(
    base_model, "Fernandosr85/fatobr-cvm-entity-scoped-adapter",
)

prompt = """Classify the following Brazilian regulatory filing with respect to the target entity below.
Target entity: BRF S.A.

Text:
A BRF S.A. ("BRF" ou "Companhia") comunica ao mercado que recebeu notificacao da
BlackRock, Inc. informando alteracao de participacao acionaria, reduzindo sua
posicao para aproximadamente 3,4% das acoes ordinarias de emissao da Companhia.

Answer with EVENT, STATUS, SCOPE, and SIGNAL, one value each, in this exact format:
EVENT=<value>
STATUS=<value>
SCOPE=<value>
SIGNAL=<value>"""

inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_new_tokens=64, do_sample=False)
print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:], skip_special_tokens=True))

# Expected:
# EVENT=REGULATORY
# STATUS=CONFIRMED
# SCOPE=TARGET_ENTITY
# SIGNAL=NEUTRAL

Inference note. The 109B base does not fit on free-tier (T4/P100) GPUs; a larger-VRAM GPU is required to load it.


Evaluation results

Training win rates (Adaption internal)

ModelWin Rate (in-domain)Win Rate (Corporate & Business)
Base (Llama-4-Scout-17B-16E-Instruct)27%43%
Adapted73%57%

A +46 point improvement in-domain. Unlike a typical task-specific adapter, the Corporate & Business reference category also improved (+14) rather than regressing — consistent with a closed-vocabulary task, where the win-rate judge has little room to reward style over correctness. No catastrophic forgetting was observed on the reference category.

Fase 1 diagnostic (simple prompt vs. scaffolded label)

There is no independent human-labeled reference in Portuguese for this task, so the table below is not an external-ground-truth baseline. It measures whether a simple prompt (label lists only, no per-value definitions) reproduces what a carefully-scaffolded prompt produces:

FieldAgreement, eval setAgreement, OTHER_ENTITY slice (n=12)
EVENT83.3%90.9%
STATUS76.2%90.9%
SCOPE95.2%36.4%
SIGNAL71.4%45.5%

The eval-set SCOPE figure is dominated by TARGETENTITY rows and says little. On the genuine OTHERENTITY slice, SCOPE agreement drops to 36.4% — the unscaffolded model defaults to TARGET_ENTITY and attributes another party's event to the tagged entity roughly two times in three. Learning that entity-scope distinction is what this adapter is trained to do.

A holdout evaluation of this adapter against fatobr_sft_eval.jsonl (per-field accuracy, with the OTHER_ENTITY slice reported separately) is the comparable number and is pending; it requires loading the 109B base on adequate GPU. Fill this in before treating the adapter's accuracy as established.

Train/eval metrics

MetricValue
Loss curvedecrease then plateau
Train vs validationtracked closely, no overfit divergence
LR schedulercosine (warmup 0.05)
Gradient norminitial spike, stable thereafter

Model details

FieldValue
Base modelmeta-llama/Llama-4-Scout-17B-16E-Instruct (109B, 16-expert MoE)
Training methodSupervised Fine-Tuning (SFT) + LoRA
LoRA rank (r)16
LoRA alpha32
LoRA dropout0
Trainable modulesk/o/q/vproj + sharedexpert (gate/up/down) + feed_forward (gate/up/down)
Epochs1
Batch sizemax
Learning rate5e-5 (cosine, 0.5 cycles)
Warmup ratio0.05
Weight decay0.05
Max grad norm1.0
Train on inputsfalse

Training dataset

[Fernandosr85/adaption-brazilian-regulatory-filings](https://huggingface.co/datasets/Fernandosr85/adaption-brazilian-regulatory-filings)

~290 prompt/completion pairs, built from the CVM IPE dataset with a deliberate methodology:

StepDetail
Source year2023 (2022+ avoids the legacy OLE2 format in older filings)
CategoriesFato Relevante and Comunicado ao Mercado only
Text extractionPer-page; pages below a character floor (chart/table-only) dropped
ExcludedInvestor decks / earnings calls (multi-event, don't map to one label set)
IdentityAnchored on CNPJ (stable across renames), name read from the filing text
Second entityFilings naming a genuine second entity labeled once per entity, to exercise SCOPE; service providers (auditors, advisory banks, rating agencies, the exchange/regulator) filtered out
CompletionsClosed-taxonomy, not platform-regenerated
SplitGrouped by filer CNPJ, stratified by SIGNAL, best of N folds

Note on corporate renames. The CVM index reports a company's current legal name for a given CNPJ, even on documents filed years before a rename. Five real cases in this corpus (3R→Brava Energia, CTEEP→ISA Energia Brasil, Aliansce Sonae→Allos, Omega→Serena Energia, Via→Grupo Casas Bahia) required anchoring identity on CNPJ and reading the name from the filing text rather than trusting the index name.


Known limitations

  • —Completion regeneration. Adaptive Data regenerates completions on every run; a freeform Blueprint cannot enforce membership in a closed label set. This adapter was trained on the original (verbatim) completions, not the platform-enhanced ones, which invented values outside the taxonomy (observed EVENT/SCOPE fabrications such as Ownership Change, Divestiture, Entity-Specific in the Enhanced column). Downstream users of the platform on closed-label tasks should map the original completion column.
  • —Pilot scale. ~290 filings; the genuine OTHER_ENTITY slice is small (~12 rows), so every figure on that axis is directional, not conclusive.
  • —Model-generated reference labels. The training labels are produced by a language model against the closed taxonomy, traceable to a per-row justification, but not human-adjudicated.
  • —Holdout accuracy pending. The Adaption win rate is the platform's internal metric; a per-field holdout evaluation of this adapter is not yet run (see the diagnostic note above).

Model repositories


Credits


Disclaimer

Experimental research artifact submitted to the AutoScientist Challenge 2026 (Market-Analysis & News category). Classification outputs are automated and require review before any operational use. Derived from public CVM data; the exact terms-of-use text was not independently confirmed at the time of writing and should be verified before redistribution.