|
Download README.md from Olyxee/FinIR-Intent: direct link, hf CLI and curl.
- Browser
- Download file 11.6 kB
-
https://huggingface.co/Olyxee/FinIR-Intent/resolve/main/README.md
- Command line
-
hf download hf://Olyxee/FinIR-Intent/README.md
-
curl -L -o README.md https://huggingface.co/Olyxee/FinIR-Intent/resolve/main/README.md
11.6 kB
| license: apache-2.0 | |
| language: en | |
| tags: | |
| - finance | |
| - structured-generation | |
| - rule-based | |
| - finir | |
| # Model Card: FinIR-Intent (baseline v0.1.0) | |
| **This is a deterministic structured-output baseline, not a trained language model.** | |
| It maps a natural-language financial instruction to the canonical **FinIR Intent | |
| Contract** (a versioned JSON envelope) using a fixed, fully offline rule set. There | |
| are no neural weights in this repository. | |
| ## What FinIR is | |
| [FinIR](https://github.com/Olyxee/finir) is a financial intermediate representation | |
| and incremental execution runtime for AI systems: a finance-typed computation graph | |
| that is validated, compiled, and evaluated with dependency-aware incremental reuse. | |
| It is published on PyPI (`pip install finir`, runtime `0.1.0`). | |
| ## What FinIR-Intent is | |
| FinIR-Intent is the natural-language layer: | |
| ``` | |
| natural-language financial request -> FinIR-Intent -> canonical FinIR Intent Contract (v1.0) | |
| ``` | |
| It performs **no financial computation**. Interpretation and execution are strictly | |
| separated: FinIR-Intent only produces the envelope; the FinIR runtime validates and | |
| executes it (`finir.intent.execute_intent` / `FinancialModel.apply_intent`). | |
| ## The problem it solves | |
| Letting an AI system "just compute" a financial what-if invites silently invented | |
| numbers and unit/currency errors. FinIR-Intent constrains the language model's job | |
| to emitting a **typed, validated intent**; the runtime is the single authority on | |
| whether that intent is executable and what it computes. Vague language becomes an | |
| explicit `ambiguous` status instead of a fabricated percentage. | |
| ## What it is / is not | |
| - **Is**: a small, dependency-free, offline pattern-matching compiler | |
| (`src/finir_intent/baseline.py`) — no network, no external LLM/API calls, fully | |
| reproducible. It implements the same `finir.intent.IntentCompiler` seam a future | |
| LLM-backed compiler would, so it is a drop-in baseline to measure against. | |
| - **Is not**: a trained/fine-tuned Transformer. Per the workstream brief, "the first | |
| milestone is not model training… only after the baseline is measured should we | |
| decide whether fine-tuning a small open model provides a meaningful improvement." | |
| This baseline exists to make that measurement possible. | |
| ## Hugging Face artifact type | |
| Because v0.1.0 ships **code, not weights**, the natural representation is a | |
| **model repository that contains the baseline package plus this card** — a | |
| code/inference repo, not a weight checkpoint. The companion benchmark ships as a | |
| **Datasets** repo, and a **Space** demonstrates the end-to-end flow against the real | |
| runtime. The page makes explicit that this is a baseline compiler, not neural | |
| weights. (See `../release/huggingface/` for the export layout.) | |
| ## Schema / runtime compatibility | |
| - **FinIR Intent schema version:** `1.0` | |
| - **Compatible FinIR runtime:** `>=0.1.0,<0.2.0` (verified against the public PyPI | |
| `finir==0.1.0`) | |
| - **FinIR-Intent baseline version:** `0.1.0` | |
| - The canonical contract is owned by the core `finir` package | |
| (`finir.intent.json_schema()`, `schemas/finir-intent-v1.schema.json`). This | |
| package **consumes** it and never redefines it. | |
| ## Supported operations | |
| | operation | meaning | | |
| |---|---| | |
| | `relative_change` | `new = current × (1 + value)` (dimensionless decimal; `-0.08` = −8%) | | |
| | `set` | `new = value` (with optional `unit` / `currency`) | | |
| | `absolute_change` | `new = current + value` (with optional `unit` / `currency`) | | |
| | `range` | sweep `target` over `[min, max]` in `steps` (sole op) | | |
| | `scenarios` | named scenarios, each a simultaneous operation set | | |
| ## Supported targets | |
| Raw model-input node names (no canonical ontology; alias resolution happens in this | |
| package only, never in the contract): `revenue`, `cogs`, `opex`, `payment_terms`, | |
| `accounts_payable`, `inventory`, `capex`, `debt`, `interest_rate`, `cash`, `price`, | |
| `volume`. | |
| ## Ambiguity / unsupported / invalid behavior | |
| - **Ambiguous** — a target with no parseable quantity, or vague language → `status: | |
| "ambiguous"`, empty operations. **No number is ever invented.** Conflicting | |
| operations on one target (e.g. "increase revenue by 5% and also cut revenue by | |
| 10%") also map to `ambiguous` rather than silently picking one. | |
| - **Unsupported** — clearly out-of-domain (acquisitions, mergers, hiring/layoffs, | |
| IPOs/going public, litigation, buybacks, bankruptcy) → `status: "unsupported"`. | |
| - **Invalid (semantic)** — a structurally valid but semantically wrong instruction | |
| (a currency the target does not use, a `days` unit on a money target) is | |
| **transcribed faithfully, never "corrected"**; the FinIR runtime rejects it at | |
| execution. This package performs no semantic check itself (no duplicated execution | |
| logic). | |
| ## Evaluation methodology | |
| Reproduce (deterministic; no network, no LLM): | |
| ```bash | |
| pip install finir==0.1.0 | |
| cd finir_intent | |
| pip install -e ".[dev]" # or: PYTHONPATH=src, plus jsonschema | |
| python eval/evaluate.py # writes eval/results/latest.json | |
| ``` | |
| `eval/evaluate.py` runs the baseline over every | |
| `intentbench/examples/intentbench_v1.jsonl` example, validates each prediction | |
| against `finir.intent.json_schema()` (the canonical schema), scores it against the | |
| paired **ground-truth** expected intent, and — for every executable prediction — | |
| actually executes it against a small reference `FinancialModel` | |
| (`src/finir_intent/reference_model.py`) via the real `finir.intent.execute_intent`. | |
| Every number below is computed from that run; none is hand-typed. | |
| ### Benchmark split (anti-leakage) | |
| FinIR-IntentBench is split into **core** (in-distribution phrasing the rule set is | |
| built to support) and a held-out **stress** subset (paraphrases the baseline was | |
| **not** tuned against — unlisted verbs, fractions, magnitude suffixes, idioms). The | |
| baseline was deliberately **not** modified to pass stress cases, so the stress | |
| numbers are an honest measure of the rule set's real coverage gap, not a tuned | |
| score. | |
| ## Evaluation results | |
| Produced by an actual run of `python eval/evaluate.py` on | |
| `intentbench_v1.jsonl` (183 examples: 143 core, 40 stress). Full per-example output, | |
| including every prediction and its execution outcome against the real runtime, is in | |
| `eval/results/latest.json`. **Re-run the command above to reproduce** if the code has | |
| changed. | |
| | metric | overall (n=183) | core (n=143) | stress (n=40) | | |
| |---|---|---|---| | |
| | schema validity | 1.0000 | 1.0000 | 1.0000 | | |
| | status accuracy | 0.9344 | 1.0000 | 0.7000 | | |
| | operation accuracy | 0.9515 | 1.0000 | 0.7500 | | |
| | target accuracy | 0.9515 | 1.0000 | 0.7500 | | |
| | value accuracy | 0.9363 | 1.0000 | 0.5833 | | |
| | unit accuracy | 1.0000 | 1.0000 | 1.0000 | | |
| | currency accuracy | 1.0000 | 1.0000 | 1.0000 | | |
| | ambiguity precision | 0.8409 | 1.0000 | 0.5333 | | |
| | ambiguity recall | 0.9737 | 1.0000 | 0.8889 | | |
| | ambiguity F1 | 0.9024 | 1.0000 | 0.6666 | | |
| | multi-operation exact-match | 0.9000 | 1.0000 | 0.0000 | | |
| | scenario exact-match | 1.0000 | 1.0000 | n/a | | |
| | runtime execution success (executable preds) | 1.0000 | 1.0000 | 1.0000 | | |
| | semantic-rejection correctness | 1.0000 | 1.0000 | 1.0000 | | |
| **Do not read the overall numbers as a headline score.** They are a blend of a | |
| saturated core set and a deliberately hard stress set. The core row shows what the | |
| baseline reliably does; the stress row shows where a fixed rule set breaks. | |
| ## Known failure cases (from the stress subset) | |
| Every current stress failure is one of two kinds — and **11 of 12 are conservative | |
| refusals, never an invented number**: | |
| - **Refuses (safe):** `valid → ambiguous` on phrasing outside the rule set — | |
| fractions/idioms ("Reduce COGS by a fifth", "Double the unit price", "Halve | |
| inventory"), an unlisted-target reference ("Increase AP by R2,000,000", "Reduce | |
| the wage bill by 6%"), and an unlisted additive idiom ("Add R5,000,000 to opex"). | |
| - **Refuses (safe):** `unsupported → ambiguous` on out-of-domain phrasing the | |
| vocabulary does not list ("Spin off the retail division", "Issue new equity", | |
| "Relocate the head office", "Replace the CEO"). | |
| - **Value errors (status still valid):** an unlisted direction verb defaults the | |
| sign to positive ("Slash opex by 12%" is parsed as +12%), and a magnitude suffix | |
| on a digit is not expanded ("Increase opex by R5m" is parsed as R5, not R5m). | |
| - **The one genuinely unsafe failure:** "Grow cogs by 4% but also reduce cogs by 2%" | |
| is parsed as a single +4% change because `but also` is not a clause separator, so | |
| the conflicting second operation is dropped instead of triggering `ambiguous`. | |
| This is the only stress case where the baseline commits to a number it should have | |
| refused; it is tracked for a future fix. | |
| ## Limitations | |
| This is a fixed rule set — a hand-authored alias table, a small number-word | |
| vocabulary, keyword-anchored regexes — **not** a trained model. Any phrasing outside | |
| what is enumerated in `src/finir_intent/baseline.py` falls back to `ambiguous` | |
| rather than being guessed. It does not handle: fractional/idiomatic magnitudes ("a | |
| fifth", "double", "halve"), magnitude suffixes on digits (`R5m`, `$2m`, `R1.2bn`), | |
| unlisted direction verbs (slash/shave/ramp/shrink…), unlisted target aliases, | |
| period/time scoping (forbidden by the v1.0 contract), or conflicting operations | |
| joined by connectives other than `and`/`,`/`;`. Growing FinIR-IntentBench with new | |
| adversarial paraphrases (as the stress subset does) is the honest way to keep | |
| measuring this gap rather than hide it. | |
| ## Fixed parser issues (regression-tested) | |
| - **Word-boundary matching** for direction and unsupported words: naive substring | |
| checks previously false-positived on ordinary English ("up" inside | |
| "supplier"/"group" flipped a decrease's sign; "merge" inside "emergency" and "sue" | |
| inside "issue" misclassified valid instructions as `unsupported`). | |
| - **`set <money-target> to N%`** now refuses (`ambiguous`) instead of silently | |
| becoming a relative change. | |
| - **Spelled-out numbers** ("five percent", "five million rand") parse via a small | |
| fixed number-word vocabulary. | |
| - **`trim`/`trims`** added to the down-direction words ("trim cogs by 4 percent" → | |
| −4%). | |
| - **`boost`/`boosts`, `raises`** added to the up-direction words. | |
| - **Layoff/going-public phrasings with a number or filler between the trigger | |
| words** ("fire 100 employees", "take the company public") are now correctly | |
| `unsupported`, anchored to headcount/listing nouns so "fire up the pipeline" is not | |
| a false positive. | |
| All are covered by unit tests in `tests/test_baseline.py` and by dataset entries. | |
| ## License | |
| Apache-2.0, matching the core FinIR repository. The benchmark is entirely synthetic; | |
| no real company or personal data. | |
| ## Repository & dependency | |
| - Source & docs: https://github.com/Olyxee/finir (workstream under `finir_intent/`) | |
| - Runtime dependency: `finir>=0.1.0,<0.2.0` — `pip install finir` | |
| - Intent Contract spec: `docs/intent-contract.md`, `docs/huggingface-intent-handoff.md` | |
| ## Attribution | |
| The FinIR-Intent Hugging Face workstream (baseline, benchmark, evaluation, Space) was | |
| contributed by **Alisha Fatima** ([@AlishaFatima16](https://github.com/AlishaFatima16)). | |
| The core FinIR runtime and the canonical FinIR Intent Contract are maintained by | |
| Olyxee. | |
| ## Links | |
| - **FinIR runtime (PyPI):** https://pypi.org/project/finir/ — `pip install finir` | |
| - **FinIR source (GitHub):** https://github.com/Olyxee/finir | |
| - **FinIR-IntentBench (dataset):** https://huggingface.co/datasets/Olyxee/FinIR-IntentBench | |
| - **FinIR Space (demo):** https://huggingface.co/spaces/Olyxee/FinIR-Intent-Demo | |