Open release
Here are the receipts.
The dataset, the scripts that built it, the trained weights, and the result of the run. Where every row came from and how it was checked. Four commands you can run yourself to confirm the counts. And the training result, which was a regression, reported with the reason rather than buried.
The artifacts
Six links, all live.
Dataset on two hosts, weights on two hosts, the pipeline that built the dataset, and a running interface. Each card says what is inside, so you know what you are getting before you click.
manifesta/verified-math-code-17k
17,000 rows as parquet, 6 columns, 0 missing values. Plus the dataset card, the build manifest and the training blueprint.
aivarasnavardauskas/verified-math-code-17k
The same 17,000 rows, mirrored, so the release does not depend on one host staying up.
verified-math-code-17k/build
The nine scripts that produced the file: pool expansion, three domain builders, two verifiers, hardening, and final assembly.
manifesta/adaption_verified_math_code_instruct
The LoRA adapter, 43,856,576 bytes, plus adapter_config.json and trainer_state.json, which is where the gradient numbers below come from.
aivarasnavardauskas/adaption_veri-35303907
The same adapter on Kaggle. The slug carries the UUID Adaption's export assigned it.
manifesta.adaptionlabs.app
A second interface built on this model, running on Adaption. It shows the working, not just the answer.
What is inside
17,000 rows, and where each one came from.
Six columns, all populated, zero missing values anywhere. Two of them do the real work. source names the corpus a row came from. verify_level says how that row was checked, or admits that it was not. Adaption ingested 17,586 rows from this corpus for the training run.
- rows published0
- columns, 0 missing0
- independently verified0.0 percent
- named source corpora0
column shape, as published
Provenance, by source
17,000 of 17,000 attributedSeven public corpora, each named in the rows it produced. The licences are what the upstream publishers state. Check them yourself before you rely on this table, because upstream terms change and mine is a snapshot.
| Source | Rows | Share | Publisher licence | Domain |
|---|---|---|---|---|
| OpenMathReasoning | 4,380 | 25.8% | CC-BY-4.0 | math |
| OpenCodeInstruct | 3,770 | 22.2% | CC-BY-4.0 | code |
| OpenMathInstruct-2 | 3,248 | 19.1% | CC-BY-4.0 | math |
| Tulu-3 | 3,108 | 18.3% | ODC-BY | general |
| OpenR1-Math | 1,476 | 8.7% | Apache-2.0 | math |
| Dolly-15k | 632 | 3.7% | CC-BY-SA-3.0 | general |
| code_contests | 386 | 2.3% | Apache-2.0 / CC-BY-4.0 | code |
| Total | 17,000 | 100.0% | CC-BY-SA-4.0 aggregate | all |
Verification, by level
13,260 of 17,000 verified13,260 of 17,000 rows carry independent verification. That is 78.0 percent. The other 3,740 are general rows and they carry none. I could have called the whole file verified and nobody would have checked. Owning the gap is what makes the 78 percent worth anything.
verify_level: independent9,104 rowsMath. The answer is checked against an independent gold standard three ways: exact, numeric, and symbolic with SymPy. All three must agree.
verify_level: executed4,156 rowsCode. The solution is run against its unit tests in a sandboxed subprocess. Every test must pass or the row is dropped.
verify_level: -3,740 rowsGeneral. Not verified. This is anti forgetting ballast, kept so a fine tune does not lose broad instruction following. It is labelled in the data so you can filter it out.
Check it yourself
Do not take my word for it. Run these.
Four calls. No account, no key, no login. Each one settles a number I have put on this page, and the output you should get back is printed next to it. If I have something wrong, one of these catches me.
- 01runnable
The dataset has 17,000 rows and 6 columns.
Hugging Face computes this from the parquet file itself. It is not a number I typed into a card.
the command
curl -s "https://datasets-server.huggingface.co/size\ ?dataset=manifesta/verified-math-code-17k" \ | python -c "import sys,json; s=json.load(sys.stdin)['size']['configs'][0]; \ print(s['num_rows'], s['num_columns'])"what it returns
17000 6If the published file ever stops matching the row count I state, this command says so before I do.
- 02runnable
13,260 of 17,000 rows carry verification, and 0 values are missing.
The same service counts every distinct value in every string column, source and verify_level included.
the command
curl -s "https://datasets-server.huggingface.co/statistics\ ?dataset=manifesta/verified-math-code-17k&config=default&split=train"what it returns
verify_level independent 9104 · executed 4156 · "-" 3740 source OpenMathReasoning 4380 · OpenCodeInstruct 3770 OpenMathInstruct-2 3248 · Tulu-3 3108 OpenR1-Math 1476 · Dolly-15k 632 code_contests 386 nan_count 0 on all six columns9,104 plus 4,156 is 13,260 of 17,000, which is 78.0 percent. The other 3,740 are general rows that carry no verification. They are marked in the data, not hidden in it.
- 03runnable
The weights exist and download.
An empty weights repo looks identical to a full one from the outside. Ask the CDN for the file size.
the command
curl -sIL https://huggingface.co/manifesta\ /adaption_verified_math_code_instruct\ /resolve/main/adapter_model.safetensors \ | grep -i "^HTTP\|^content-length"what it returns
HTTP/1.1 302 Found HTTP/1.1 200 OK content-length: 4385657643,856,576 bytes of LoRA adapter. trainer_state.json sits beside it in the same repo, and that is where every training number below comes from.
- 04runnable
The declared base model resolves.
adapter_config.json names a base model. That name has to be a repo that exists, or nothing can load the adapter at all.
the command
curl -s -o /dev/null -w "%{http_code}\n" \ https://huggingface.co/api/models/google/gemma-4-31B-itwhat it returns
200adapter_config.json says base_model_name_or_path is google/gemma-4-31B-it. The model card says the same thing. The Hub returns 200. All three agree.
Rather click than type. The raw endpoints: size, statistics, adapter_config.json, and the base model.
The training result
The adapted model lost.
AutoScientist scored it against the base, head to head. Adapted 46. Base 54. It went backwards by 8 points and there is no reading of that which makes it a win. So here is what happened, from trainer_state.json inside the published weights.
why it went backwards
- 01
The run was unstable.
29 of the 59 optimizer steps came in over the clip threshold of 2. The median norm was 1.97 and the peak was 677.21. Clipping at 2 when the true norm is 677 keeps the direction and throws the magnitude away, so on half the steps the optimizer stopped following the loss surface and started taking equal length strides in noisy directions.
- 02
59 steps is a nudge, not a fine tune.
At that step count the weights barely leave where they started. Most of what the eval scored was still the base model, plus a half applied update.
- 03
The base was already good at this.
gemma-4-31B-it is a 31B instruction tuned model. Boxed math answers and Python that passes its tests are exactly what a frontier instruction tune spends its effort on. I picked a domain where the base had almost nothing left to learn.
gradient norms, from the run state
The second block is a chart QA run I did on the same platform, same clip threshold. It peaked at 0.72 and never clipped once in 34 steps. That is what a stable run looks like. Put the two side by side and the maths run is not close.
The data quality pass, separately
not the headlineAdaptive Data scores the corpus itself, before and after its own pass. That measures the data, not the trained model, which is why it sits down here and not at the top. The corpus went in at 8.0 out of 10, the highest starting point of anything I built for this, and came out at 8.2. Very little room to move when you start that high.
| Metric | Before | After |
|---|---|---|
| Quality score | 8.0 | 8.2 |
| Grade | B | B |
| Percentile | 15.3 | 17.8 |
What the run actually taught me
Across every run I did for this, the win rate tracked how weak the base model was in the target domain. Not how big the dataset was, not how clean. Data quality sets a ceiling on what a fine tune can teach. It does not create headroom that was never there.
I would rather publish this than a number I cannot account for. Every figure above is one download away from anyone who wants to check it. Read the full model card.
Reproduce
The dataset is the output of a pipeline, and the pipeline ships.
Nine scripts, published in the dataset repo under build/. This is not a hand curated pile with a story attached to it. Run them in this order and you get the file.
All nine, the audit evidence, and a verifier that rechecks every number on this page against the live published files, are in one public repo: A1VARA5/verified-math-code-17k. verify.py is standard library only, so there is no install step and no account. It runs 23 checks, and the same 23 run on a daily schedule, which means if anything on this page stops being true the badge goes red without me touching it.
- 01
Expand the candidate pools
build/expand_pools.pyPulls candidates from the seven upstream corpora and builds a working pool per domain. Most of what enters here does not survive.
- 02
Build the math candidates
build/build_math.pyShapes math rows into the problem and worked_solution contract, and attaches the independent gold answer each row will be checked against.
- 03
Build the code candidates
build/build_code.pyShapes code rows and attaches the unit tests each solution will have to pass.
- 04
Build the general slice
build/build_general.pyAssembles the 3,740 row anti forgetting slice. This one is deliberately not verified, and it is labelled that way in the output.
- 05
Verify the math
build/verify_core.pyChecks every math answer against its gold standard three ways: exact, numeric, and symbolic with SymPy. All three have to agree or the row is dropped. 9,104 rows survive as verify_level independent.
- 06
Execute the code
build/verify_code.pyRuns every code solution against its unit tests in a sandboxed subprocess. Any failing test drops the row. 4,156 rows survive as verify_level executed.
- 07
Harden, dedupe, decontaminate
build/harden.pyEnforces the output contract, removes duplicates, and decontaminates by 13 gram overlap against the genuine held out splits of GSM8K test, MBPP test and HumanEval.
- 08
Assemble and write the manifest
build/assemble_v3.pyWrites the final 17,000 rows and the machine readable build manifest: counts by domain, by source, by verification level and by difficulty.
- 09
Shared helpers
build/common.pyNot a stage. The IO, normalisation and licence bookkeeping the other eight import.
then run it yourself
The training side is reproducible too. The blueprint used for the Adaption run ships as extras/BLUEPRINT.md, and the counts the build produced ship as extras/build_manifest.json. The run itself was done on Adaption, and the platform is documented at docs.adaptionlabs.ai.
Licence
CC-BY-SA-4.0, and 632 rows are the reason.
One slice forces it. 632 rows come from Dolly-15k, which is CC-BY-SA-3.0 and carries a share alike obligation. Share alike in one source propagates to the whole release, so the honest aggregate is CC-BY-SA-4.0, even though the other six sources are attribution only or looser.
If share alike does not work for you, one filter fixes it. Drop source == "Dolly-15k" and 16,368 rows remain, attribution only. All 632 sit in the unverified general slice, so dropping them costs you no verified data.
Check these licences against the upstream publishers before you rely on them. The table above is what those projects state today and terms change. The per source breakdown is in the dataset card and the source column carries it on every row, so you can work out the licence position of any subset you build.