mindXtrain / llm.txt
Gregory-L's picture
bankml: the verified CPU engine as backend, serve target and imprint probe (#1)
730c5bb
Raw History Blame Contribute Delete
9.28 kB
# llm.txt β€” mindXtrain, for another model
You are reading the operator's note for an AI that has to work on this repository. It says what this
is, what was just built, what is true, what is *not* true, and the traps that cost real hours. Prefer
this file over inference; where it disagrees with a comment, check the code and fix one of them.
## What mindXtrain is
A production training framework for fine-tuning open-weight LLMs: `init β†’ bench β†’ train β†’ imprint β†’
eval β†’ serve β†’ publish`, a Typer CLI (`mindxtrain`), a FastAPI operator app, and β€” as of this work β€”
a Gradio UI and a Hugging Face extension. It trains on an AMD MI300X when there is one and on **two
CPU cores** when there is not; the CPU path is not a toy, it produced 77 generations of a live system.
Source of truth: <https://huggingface.co/PYTHAI/mindXtrain> (this repository). The GitHub original,
<https://github.com/Professor-Codephreak/mindXtrain>, is archived for posterity β€” Professor Codephreak's pioneering work,
read-only. It is consumed by
[mindX](https://mindx.pythai.net), which writes its own memory into a corpus and trains on it.
## The one claim, and its limits
> A 135M model, two CPU cores and 70 minutes moved **proof-of-recall by +0.10**.
That is generation 39, published as <https://huggingface.co/PYTHAI/mindXtrain39>. It proves the loop
closes: dream β†’ corpus β†’ weights β†’ a gate that can say no. It does **not** prove identity (the coach
measured 16% of answers speaking as mindX) and it does not prove reasoning. **Generations 42–74 were
all `proof_rejected`.** If you write a sentence that implies otherwise, you are wrong.
## What was just built (read these first)
| path | what it is |
|---|---|
| `mindxtrain/ui/app.py` | the whole framework as one Gradio surface. Tiers **Basic Β· Advanced Β· Scientific** β€” complexity is a dial, not a wall. Rooms: Forge (train) Β· Gate (imprint) Β· Measure (eval) Β· Serve Β· **Coach** Β· Hub Β· Bench Β· Runs |
| `mindxtrain/ui/metrics.py` | diagnostics parsed from the trainer's own log. Every metric carries its **unit** and **source**. It never invents a step |
| `mindxtrain/ui/theme.py` | one dark palette that survives Gradio 5 and 6 |
| `mindxtrain/hf/extension.py` | the Hub as this framework needs it: `account`, `pull_base`, `warm`, `publish_generation`, `push_dataset`, `lineage`, `push_space` |
Everything in the UI **shells out to the real CLI**. No room re-implements training. If a number
appears in the UI, it was parsed from a file the trainer wrote β€” that invariant is the design.
## How to work here
```bash
uv sync --extra ml # training deps (trl, transformers, peft, accelerate)
uv sync --extra chain # huggingface_hub, for mindxtrain.hf
uv run pytest -q # the suite must stay green
uv run mindxtrain --help # the verbs are the contract
uv run python -m mindxtrain.ui.app # the UI at :7862
```
- Add a **verb**, not a script: the CLI is the interface everything else drives.
- Add a **recipe** (`mindxtrain/train/recipes/*.yaml`), do not hardcode hyperparameters.
- A run that cannot be re-hashed from its manifest is a story, not a result (`mindxtrain receipt`).
## Traps that cost hours (all of these are real)
1. **A LoRA has meaning only on the tensors it was trained on.** For months the fallback Modelfile
stacked a SmolLM2 adapter on a Qwen3 base: different architecture, hidden size and vocab. Nothing
downstream could tell β€” `ollama create` succeeds and the ascent records `promoted`. Verify the base
against `adapter_config.json:base_model_name_or_path` before serving.
2. **`list_repo_tree` yields `RepoFile` *and* `RepoFolder`, both with `.path`.** Only
`repo_info().siblings` carry `.rfilename`. Reading the wrong attribute makes a scan report
"nothing on the Hub" while the repo is full. This exact bug hid 69 published generations.
3. **The Hub checks a Space's ZeroGPU quota *before* it checks existence.** `create_repo(exist_ok=True,
space_hardware=…)` on an existing Space answers **402** once the account's two free slots are used.
Check `repo_exists` first.
4. **A Space README's `short_description` must be ≀ 60 characters**, or `upload_folder` is refused.
5. **Membership is not write scope.** A token can belong to an org and still be unable to write it.
6. **Never put a write-scoped token on a public Space.**
7. **Gradio 6** moved `theme`/`css` to `launch()` and dropped `Chatbot(type=…)`; its chat history
returns content as a *list of parts*. Read the installed signature; do not pin a major.
8. **ZeroGPU quota belongs to the caller.** Anonymous visitors share a small pool; a signed-in visitor
spends their own minutes (5/day free, 40 PRO). `@spaces.GPU` functions must be defined at import,
and the model must be loaded at module level β€” the GPU workers are forked after startup.
9. **Ollama's lineage models here were built from converted GGUF blobs**, not from a safetensors
folder. `ollama create` pointed at a safetensors directory can hang silently on this version.
## The gate, and why it is the point
`mindxtrain imprint` measures **recall before vs after** on the same probes, decoding greedily with
`repetition_penalty=1.3`, `no_repeat_ngram_size=3`. Change the decoding and the number stops being
comparable. The floor is calibrated against a **null** (an untrained random-init adapter), not chosen.
A run that fails the gate is recorded as failed and is not served. *That refusal is the product.*
`mindxtrain imprint-bankml` is a **second instrument**, not the gate: probes through
[bankml](https://github.com/cryptoAGI/bankml) (`bankml serve --native`, token-identical to llama.cpp
b11192) at temperature 0, a fixed seed and **no penalties**, a receipt (model sha256) per utterance.
Its scores are tagged `<scorer>/bankml-greedy` and are **not comparable** with the gate's. Never mix
them. Backends the operator knows: `openai_compat`, `ollama`, `vllm`, `bankml` β€” see `docs/bankml.md`;
a bankml HTTP 400 is a `BankmlRefusal` with its reason, and is never retried with altered parameters.
Serve targets: `mindxtrain serve run.yaml --to ollama|bankml|vllm|sglang`. `vllm` / `sglang` launch the
OpenAI-compatible server detached (LoRA native over the base by default, `--merge` to merge; log + pid
under `out/runs/<run>/serve/<to>/`), return once `/v1/models` lists the tag, `--dry-run` prints the
argv, `--stop` ends it; GPU-only configs are refused on a CPU host β€” see `docs/serve.md`.
## The teaching artifacts
Published beside the weights at `PYTHAI/mindXtrain39`, and mirrored in mindX at
`mindx/godel/mindxtrain/policy/`:
- **`educational.policy.json`** β€” how to duplicate a successful run, written from gen39's own log
(116 steps, 2 epochs, 4,201 s, train loss 1.65, eval 1.225, LoRA r16/Ξ±32, 33% CPU at nice 19).
- **`bootcamp.impression.json`** β€” drill β†’ impression: build the corpus, train, probe the *frozen base
first*, probe the trained model on the same battery; the difference is the impression.
- **`impression.bootcamp.json`** β€” impression β†’ drill: join every probe back to the row that taught it,
raise what was not recalled, lower what holds, and let that write the next recipe.
- **`THOT.json` + `inft/`** β€” the generation as a canonical record named by its own CIDv1
(`thot-bafkreiav76jv5zi4d63ns6zaamp3krolfzuqzrbquwumyslmej274ysaue`), with ERC-7857 facets. Minting
is a hand-off to AgenticPlace and is signed by a human; an agent does not sign mainnet.
## Example consumer: mindX, its docs and its Hub map
mindXtrain stays agnostic: it trains whatever corpus you give it. mindX is the reference consumer, so the worked
example lives in [`examples/mindx/`](examples/mindx/HUGGINGFACE_MAP.md) β€” every public Hugging Face repo mindX
uses (the lineage, the docs dataset, the Spaces, the licence-pinned base-model forks), with what each one is.
- mindX publishes its doctrine as a corpus-ready dataset: <https://huggingface.co/datasets/PYTHAI/mindX-docs>
(NAV, THESIS, MANIFESTO in full; sha256 per file) and the mapping of every mindX doc:
<https://huggingface.co/datasets/PYTHAI/mindX-docs/blob/main/MAPPING.md>. The gated tiers are private.
- The mindX-specific wiring (which dataset, which persona, which gate floor) lives in mindX's bridge, not here.
A new consumer copies the shape, not the names.
```python
from huggingface_hub import hf_hub_download
nav = hf_hub_download("PYTHAI/mindX-docs", "docs/NAV.md", repo_type="dataset") # the example consumer's corpus
```
Trap: if a doc's sha256 differs from the consumer's mapping, you are reading a different revision β€” pin `revision=`
to the dataset commit you trained against and record it in the run manifest.
## If you are asked to change the UI
Keep the three tiers. Keep "every number came from a file the trainer wrote". Add a room rather than
crowding one. The Coach room is the loop closing: it reads measured influence, proposes the next
recipe, and can start it β€” but it must never propose a rung the evidence already rejected.
## Tone
Say what is measured. When the honest verdict is *not yet*, say so β€” the repository does, and its
credibility is the only thing that makes the positive numbers worth reading.