Text Generation
Transformers
Safetensors
GGUF
ministral3
function-calling
tool-use
agent
ministral
experimental
conversational
Instructions to use OculusMindAI/OculusMind-ToolCall-8B-v2 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use OculusMindAI/OculusMind-ToolCall-8B-v2 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="OculusMindAI/OculusMind-ToolCall-8B-v2") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("OculusMindAI/OculusMind-ToolCall-8B-v2") model = AutoModelForCausalLM.from_pretrained("OculusMindAI/OculusMind-ToolCall-8B-v2", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use OculusMindAI/OculusMind-ToolCall-8B-v2 with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0 # Run inference directly in the terminal: llama cli -hf OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0 # Run inference directly in the terminal: llama cli -hf OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0
Build from source code
git clone https://github.com/ggml-org/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-app # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama serve -hf OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0 # Run inference directly in the terminal: ./build/bin/llama cli -hf OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0
Use Docker
docker model run hf.co/OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0
- Llama new
- LM Studio
- Jan
- vLLM
How to use OculusMindAI/OculusMind-ToolCall-8B-v2 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "OculusMindAI/OculusMind-ToolCall-8B-v2" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "OculusMindAI/OculusMind-ToolCall-8B-v2", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0
- SGLang
How to use OculusMindAI/OculusMind-ToolCall-8B-v2 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "OculusMindAI/OculusMind-ToolCall-8B-v2" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "OculusMindAI/OculusMind-ToolCall-8B-v2", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "OculusMindAI/OculusMind-ToolCall-8B-v2" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "OculusMindAI/OculusMind-ToolCall-8B-v2", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Ollama
How to use OculusMindAI/OculusMind-ToolCall-8B-v2 with Ollama:
ollama run hf.co/OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0
- Unsloth Desktop
- Pi
How to use OculusMindAI/OculusMind-ToolCall-8B-v2 with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0
Configure the model in Pi
# Install Pi: npm install -g @earendil-works/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use OculusMindAI/OculusMind-ToolCall-8B-v2 with Docker Model Runner:
docker model run hf.co/OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0
- Lemonade
How to use OculusMindAI/OculusMind-ToolCall-8B-v2 with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0
Run and chat with the model
lemonade run user.OculusMind-ToolCall-8B-v2-Q8_0
List all available models
lemonade list
- Hermes Agent
How to use OculusMindAI/OculusMind-ToolCall-8B-v2 with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use OculusMindAI/OculusMind-ToolCall-8B-v2 with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0
Configure OpenClaw
# Install OpenClaw: npm install -g openclaw@latest # Register the local server and set it as the default model: openclaw onboard --non-interactive --mode local \ --auth-choice custom-api-key \ --custom-base-url http://127.0.0.1:8080/v1 \ --custom-model-id "OculusMindAI/OculusMind-ToolCall-8B-v2:Q8_0" \ --custom-provider-id llama-cpp \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
Documentation update: Claude comparisons move to APPENDIX-claude-comparison.md; training-data, held-out and lineage notes corrected; Ollama download command updated for huggingface_hub 2.x; adapter_config.json without local paths
3a3d1b3 verified |
Download APPENDIX-looping.md from OculusMindAI/OculusMind-ToolCall-8B-v2: direct link, hf CLI and curl.
- Browser
- Download file 13.2 kB
-
https://huggingface.co/OculusMindAI/OculusMind-ToolCall-8B-v2/resolve/main/APPENDIX-looping.md
- Command line
-
hf download hf://OculusMindAI/OculusMind-ToolCall-8B-v2/APPENDIX-looping.md
-
curl -L -o APPENDIX-looping.md https://huggingface.co/OculusMindAI/OculusMind-ToolCall-8B-v2/resolve/main/APPENDIX-looping.md
13.2 kB
| # Appendix: the tool-call loop defect, and the seed sweep against it | |
| *Every number here is measured and its artifact is kept.* | |
| ## What the defect is | |
| A turn ends with the model emitting the same tool call over and over instead of | |
| stopping β sometimes the identical call, sometimes the same tool with varied | |
| arguments. The worst example we recorded ran **313 consecutive tool calls** in a | |
| single turn. In production this is not a quality problem, it is an availability | |
| one: the turn never terminates, and it consumes the budget of whatever called it. | |
| ## Scope of the claim β read this before quoting any number here | |
| Everything below was measured on **one checkpoint**: | |
| `mistralai/Ministral-3-8B-Instruct-2512-BF16` at revision | |
| `f6fae9795746f63c9be8344932f01275f3c63734`, served as Q8_0 GGUF through | |
| llama.cpp `c812c543f`, on **our** production-derived suite. | |
| **This is not a claim about "Mistral models".** A family name predicts neither the | |
| behaviour nor the licence of its next release, and this project has an expensive | |
| worked example: `Ministral-8B-Instruct-2410` is research-licensed while | |
| `Ministral-3-8B-Instruct-2512` is `apache-2.0` β same product name, opposite | |
| answers. We have not measured any other Mistral checkpoint, so we say nothing | |
| about them. What we can say is that **our pinned base exhibits the defect**, and | |
| that fine-tuning moves the rate in both directions depending on nothing but the | |
| seed. | |
| ## The base already loops | |
| | population | loop rate | worst response | | |
| |---|---:|---:| | |
| | **full faithful set (1,133 tool-turns, 1,965 items)** | **π΄ 0.09 %** (1 turn) | **111 calls** | | |
| | `select-vera` (146 tool-turns) | π΄ 0.68 % (1 turn) | 111 calls | | |
| | `screen-vera` (212 tool-turns) | π΄ 0.47 % (1 turn) | 111 calls | | |
| **The first row is the number to quote**, and all three rows are the same single | |
| event seen through different denominators β one looping turn, 111 calls, a single | |
| tool name repeated 108 times. On 146 tool-turns that one turn is 0.68 %; on 1,133 | |
| it is 0.09 %. Nothing about the base changed between those measurements, and | |
| quoting the largest of them because it is the most convenient would be reporting a | |
| sample size as a finding. | |
| The scan completed 2026-10-02 over **1,965 of 1,965 collectable items** (Q8_0, | |
| temperature 0, cap 4096), and its scorer output is kept at | |
| `benchmarks/base-scans/faithful-all-q8-cap4096/scores.json`. The name-repeat | |
| histogram is the useful shape: 1,059 turns repeat a tool name once, 52 call no | |
| tool, a thin tail reaches 10 β and then one turn sits at **108**, with nothing in | |
| between. **The defect is rare and catastrophic, not a gradient**, which is why a | |
| threshold-based gate works at all and why an aggregate rate understates it: the | |
| cost of the one turn is an unterminated production request, not 0.09 % of a | |
| quality score. | |
| So the defect is **not introduced by fine-tuning**. That matters for reading | |
| everything below: a trained arm with a non-zero rate has not necessarily been | |
| damaged, and an arm at zero has genuinely *removed* something the base does. | |
| ## How a loop is detected | |
| Three independent readings, any one of which condemns a turn: | |
| | rule | threshold | what it catches | | |
| |---|---:|---| | |
| | `maxIdenticalCallRepeat` | β₯ 8 | the identical `(name, arguments)` signature repeated | | |
| | `toolCallCount` | β₯ 200 | a runaway trajectory of any shape | | |
| | `maxToolNameRepeat` | β₯ 24 | the same tool NAME repeated, **arguments ignored** | | |
| The third rule exists because a model that loops while varying one argument field | |
| looks like progress to a signature-based check and is the same failure. | |
| **The name threshold was calibrated against production traffic, not guessed.** | |
| At 24 it is deliberately generous: a stricter setting of 12 condemns a real | |
| production turn that called `web_search` 15 times with distinct `site:` queries β | |
| legitimate work. A detector that cannot tell a loop from a thorough search is | |
| worse than none, because it teaches you to distrust it. | |
| ## The sweep | |
| Ten runs, seeds 42β51. **Identical** dataset (`l2-3f301662871f`), recipe (LoRA | |
| rank 8, dropout 0.05, scale 1.0, attention projections only, lr 2e-5 cosine), | |
| checkpoint (150), quantisation and scoring population. The seed is the only | |
| difference. | |
| A seed is not a quantity β it is the initial state of a pseudo-random generator, | |
| and here it controls three things: LoRA `A` initialisation, every dropout mask, | |
| and data order. We checked that consecutive seeds are not secretly similar: | |
| across MLX's RNG and numpy's permutation, mean |r| between adjacent seeds (0.0037 | |
| and 0.0181) sits at or below the noise floor and is no higher than between | |
| distant values like 1009 and 999983. **42β51 samples the same distribution that | |
| scattered values would.** | |
| ## Results | |
| `validFirstToolMatchPct` on `select-vera`, 146 tool-turns, cap 4096, temperature 0. | |
| | seed | score | Ξ vs base | loop rate | worst response | gate | | |
| |---|---:|---:|---:|---:|---| | |
| | base (untrained) | 80.82 β‘ | β | π΄ 0.68 % | 272 | β | | |
| | **46** | **96.58** | **π’ +15.76 pts (+19.5 %)** | **0.00 %** | 13 | **passes** | | |
| | 48 | 96.58 | π’ +15.76 pts (+19.5 %) | π΄ 0.68 % | 116 | excluded | | |
| | 43 | 95.21 | π’ +14.39 pts (+17.8 %) | π΄ 0.68 % | 292 | excluded | | |
| | 42 | 92.92 β | not comparable | 0.00 % | 13 | passes | | |
| | 45 | 93.15 | π’ +12.33 pts (+15.3 %) | 0.00 % | β | passes | | |
| | 50 | 93.15 | π’ +12.33 pts (+15.3 %) | π΄ 1.37 % | β | excluded | | |
| | 49 | 92.47 | π’ +11.65 pts (+14.4 %) | π΄ 5.48 % | β | excluded | | |
| | 44 | 91.10 | π’ +10.28 pts (+12.7 %) | π΄ 6.85 % | 313 | excluded | | |
| | 47 | 90.41 | π’ +9.59 pts (+11.9 %) | 0.00 % | β | passes | | |
| | 51 | 94.52 | π’ +13.70 pts (+17.0 %) | 0.00 % | 15 | passes | | |
| β‘ The base was collected directly on these 266 items at the same cap and | |
| temperature, three times with identical results; this is the figure the card | |
| quotes. (Re-scoring the base's 404-item screen responses on this population gives | |
| 74.66 instead β a re-score of a different run, not a measurement of this one.) | |
| β **Seed 42 is not measured on this population.** It was the original arm and was | |
| scored on `screen-vera` β 404 items, 212 tool-turns β before the sweep standardised | |
| on `select-vera`'s 266, so 92.92 is its screen-vera figure and is **not comparable | |
| to the rest of this column**. | |
| Seed 42's artifact-backed figures are: `report-vera-sealed` **95.45** (66 turns, | |
| tying seed 46), production temperature 0.35 **95.21** (146 turns), and the | |
| loop-provocation slice **100.0**. Those are the numbers to quote for it. | |
| **Five of the ten seeds loop at least once.** The rate ranges from 0.00 % | |
| to 6.85 % β ten of 146 tool-turns β from one recipe on one dataset. This is real | |
| variance in what gets trained, not measurement noise: the loop VERDICT agreed | |
| 20/20 across two collections of the same artifact (see "Is it the sampler?"). | |
| ## Is it the sampler, or the model? | |
| The screen is **not** byte-deterministic. Re-collecting the 20 busiest items | |
| against the same artifact gave 14/20 identical tool-call sequences and 19/20 | |
| identical text; one item ran 119 calls one time and 158 the next. | |
| That is the right alarm to raise and it does **not** make the gate unsound, | |
| because the gate is a **binary** per-item verdict and a 119-call and a 158-call | |
| runaway are the same verdict. Measured per item with the real scorer, over the | |
| same 20 items: | |
| | fact | agreement | | |
| |---|---| | |
| | `looped` | **20/20** | | |
| | `firstToolMatch` | 20/20 | | |
| | `validFirstToolMatch` | 20/20 | | |
| Those 20 were chosen as the **busiest** β adversarially, where instability | |
| compounds β which makes the agreement stronger evidence than a random sample. | |
| **So the difference between seed 42's zero and seed 44's 6.85 % is a property of | |
| the models, not of the sampling.** | |
| ## The gate, and what it cost | |
| Looping is a **gate**, not a ranking dimension. Any non-zero rate excludes the | |
| seed outright; survivors are then ranked on score. There is no ranking *within* | |
| non-zero, because 3 loops versus 4 is noise while zero versus non-zero is not. | |
| For most of the sweep this was free β the best score happened also to be clean. | |
| Then seed 48 scored **96.58, identical to seed 46**, 141 of 146 tool-turns for | |
| both, and loops once. It is excluded and seed 46 ships. Two models | |
| indistinguishable on the ranking metric, and the tie broken by the defect rather | |
| than by noise in the third decimal. | |
| ## "You ran ten and shipped the best one" β yes, and here is why the headline survives | |
| This table invites a fair objection: ten runs were made, the one that scored | |
| highest on `select-vera` is the one being published, so the published selection | |
| score is the maximum of ten draws and is biased upward by construction. That is | |
| correct, and it is why **the headline number is not a `select-vera` number.** | |
| The populations have different jobs, fixed before the sweep ran: | |
| | population | role | may inform selection? | | |
| |---|---|---| | |
| | `screen-vera`, `select-vera` | screening and ranking the sweep | **yes β that is their purpose** | | |
| | `report-vera-sealed` (138 items, 66 tool-turns) | the reported figure | **no β held back, scored once** | | |
| Seed 46 was chosen on `select-vera` at **96.58**, and that figure is reported here | |
| as what it is: the selection score, the maximum of ten, not a performance claim. | |
| The published claim is **95.45 on `report-vera-sealed` against the base's 86.36**, | |
| measured after selection was already settled, on items that informed no seed or | |
| checkpoint choice (they were part of the earlier screen on which training recipes | |
| were compared β README Β§2). | |
| Two consequences worth stating plainly, because they cut against us: | |
| - **The sealed figure is lower than the selection figure** (95.45 against 96.58), | |
| which is the direction selection bias predicts. We report the lower one. | |
| - **Seed 42 ties on the sealed population** (95.45, the same 63 of 66 tool-turns) | |
| while scoring 2 points lower on the selection population. With 66 tool-turns one | |
| turn is 1.5 points, so the sealed measurement cannot separate the top two β and | |
| the card says so rather than presenting the selection ordering as a ranking. | |
| **What a reader cannot check, and should know they cannot.** Nine of the ten seeds | |
| are not published, and neither are the evaluation suites β they are built from | |
| production captures. So every row in the table above except seed 46's rests on our | |
| word. The scorer outputs for all of them are kept, and the exact code, data and | |
| artifact behind each is recorded, but that record is internal. We state the rows | |
| because omitting them while claiming "selected under a loop gate" would be the | |
| weaker position, not because a reader can independently verify them. | |
| ## The runner-up, and why seed 46 was chosen anyway | |
| Seed 42 ties this model on the reported population (95.45, 63 of 66) and on the | |
| loop-provocation slice (100.0). It was separated on three other measurements: | |
| | | seed 46 (this model) | seed 42 | Ξ (46 β 42) | | |
| |---|---:|---:|---:| | |
| | `report-vera-sealed`, temp 0 (66 turns) | 95.45 | 95.45 | Β±0 | | |
| | **production temperature 0.35** (146 turns) | **97.26** | 95.21 | **π’ +2.05 pts (+2.2 %)** | | |
| | worst response on sealed | **6 calls** | 12 calls | π’ β6 calls | | |
| | loop-provocation slice | 100.0 (worst 13) | 100.0 (worst 10) | Β±0 | | |
| | `select-vera`, temp 0 (146 turns) | **96.58** | **never measured** | β | | |
| Seed 42 has no `select-vera` temperature-0 run under the published recipe: it was | |
| the original arm, scored on `screen-vera` β 404 items, 212 tool-turns, **92.92** β | |
| before the sweep standardised on `select-vera`'s 266 items, so that row cannot be | |
| filled with a comparable number and is left empty rather than approximated. | |
| **The reported figure alone could not choose between them.** Saying so is the | |
| point: with 66 tool-turns, one turn is 1.5 points, and presenting a tie as a | |
| ranking would be presenting a coin-flip as a measurement. The separation that | |
| survives is production temperature, where the two were measured on the same 146 | |
| tool-turns. | |
| ## What these numbers do not establish | |
| - **"No loop observed on 266 items" is not "never loops."** A dedicated | |
| provocation slice, built from turns that actually provoked loops, is the | |
| stronger test and is reported separately. | |
| - **A gate verdict belongs to the population it was measured on.** Seed 45 scored | |
| 0.00 % on `select-vera` and passed, then logged **1.52 % with a 124-call | |
| response** on `report-vera-sealed`. "No loop observed on 266 items" is the | |
| honest wording, and this is what it was protecting against. | |
| - **At production temperature 0.35, none of the three shortlisted seeds looped** | |
| (worst responses 12β19 calls), against 0.00β1.52 % at temperature 0 on the same | |
| items. This is suggestive and **not a finding**: the base has not been run at | |
| 0.35, so whether sampling suppresses the defect or this population simply does | |
| not provoke it either way is unmeasured. | |
| - **Run-to-run variance of the aggregate score is unbounded** on this evidence β | |
| 20 items were re-collected, not 266 β so a seed ordering separated by a | |
| fraction of a point is not trustworthy. It is sound for a coarse cut. | |
| - **One checkpoint, one suite, one quantisation.** See "Scope of the claim". | |