Instructions to use Rahspide/MNN-Pocket-0.3B-RU with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Rahspide/MNN-Pocket-0.3B-RU with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Rahspide/MNN-Pocket-0.3B-RU") 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("Rahspide/MNN-Pocket-0.3B-RU") model = AutoModelForCausalLM.from_pretrained("Rahspide/MNN-Pocket-0.3B-RU", 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 Rahspide/MNN-Pocket-0.3B-RU 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 Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M # Run inference directly in the terminal: llama cli -hf Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M # Run inference directly in the terminal: llama cli -hf Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M
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 Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M # Run inference directly in the terminal: ./build/bin/llama cli -hf Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M
Use Docker
docker model run hf.co/Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M
- Llama new
- LM Studio
- Jan
- vLLM
How to use Rahspide/MNN-Pocket-0.3B-RU with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Rahspide/MNN-Pocket-0.3B-RU" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Rahspide/MNN-Pocket-0.3B-RU", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M
- SGLang
How to use Rahspide/MNN-Pocket-0.3B-RU 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 "Rahspide/MNN-Pocket-0.3B-RU" \ --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": "Rahspide/MNN-Pocket-0.3B-RU", "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 "Rahspide/MNN-Pocket-0.3B-RU" \ --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": "Rahspide/MNN-Pocket-0.3B-RU", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Ollama
How to use Rahspide/MNN-Pocket-0.3B-RU with Ollama:
ollama run hf.co/Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M
- Unsloth Desktop
- Pi
How to use Rahspide/MNN-Pocket-0.3B-RU with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M
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": "Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use Rahspide/MNN-Pocket-0.3B-RU with Docker Model Runner:
docker model run hf.co/Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M
- Lemonade
How to use Rahspide/MNN-Pocket-0.3B-RU with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M
Run and chat with the model
lemonade run user.MNN-Pocket-0.3B-RU-Q4_K_M
List all available models
lemonade list
- Hermes Agent
How to use Rahspide/MNN-Pocket-0.3B-RU with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M
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 Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use Rahspide/MNN-Pocket-0.3B-RU with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M
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 "Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M" \ --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"
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": "Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M"
}
]
}
}
}Run Pi
# Start Pi in your project directory:
piStatus: v1 released. 1.2 B tokens, one epoch, weights in this repository, GGUF in
gguf/. Training log, checkpoints and the evaluation script live in the private repoRahspide/mnn-pocket-ru-run.
A continued-pretraining run of taobao-mnn/MNN-Pocket-0.3B-Base
that teaches it Russian while keeping English and Chinese readable. The keyboard is the use case that set the
size and latency budget.
It is trained as a plain causal LM on raw text, so it continues a typed prefix instead of answering it.
For dialogue there is a separate checkpoint — Rahspide/MNN-Pocket-0.3B-RU-Chat.
Two models, two jobs
This model — MNN-Pocket-0.3B-RU |
Sister — MNN-Pocket-0.3B-RU-Chat |
|
|---|---|---|
| Job | continue text | follow instructions |
| Input | a prefix, often mid-sentence | a system + user message |
| Output | the plausible continuation | an answer |
| Trained with | continued pretraining, 1.2 B tokens of raw text | SFT on top of this model, 50 M tokens |
| Choose it for | keyboard suggestions, autocomplete, prefix completion | chat, Q&A, short rewrites |
| Do not choose it for | assistant behaviour: it continues your question instead of answering | autocomplete: it answers instead of continuing |
The two tasks reward opposite behaviour. Trained on both jobs, one checkpoint does each badly: it answers when it should continue, and continues when it should answer.
Specs
| Base | taobao-mnn/MNN-Pocket-0.3B-Base (Qwen3 architecture, 303 M non-embedding / 361 M total) |
| Tokenizer | 65,536 tokens, byte-level BPE, `< |
| Training tokens | 1.2 B — 0.9 B ru + 0.204 B en + 0.096 B zh |
| Method | full fine-tune, 1 epoch, no LoRA |
| Steps | 36,621 × 32,768 tokens |
| Hardware | one Colab T4 16 GB, 4.8 k tok/s, ~69 h |
| Precision | fp32 master weights, fp16 autocast (T4 has no usable bf16) |
Results
100 k held-out tokens per language, identical settings for both checkpoints:
| Lang | ppl base → v1 | bits/char base → v1 | top-1 base → v1 | top-5 base → v1 |
|---|---|---|---|---|
| ru | 10.42 → 5.05 | 1.625 → 1.123 (−31%) | 46.2% → 61.0% | 69.3% → 80.6% |
| en | 21.85 → 41.16 | 1.016 → 1.225 (+21%) | 39.9% → 35.5% | 64.1% → 58.7% |
| zh | 23.95 → 51.86 | 3.274 → 4.071 (+24%) | 41.9% → 37.7% | 62.0% → 55.6% |
The published weights were re-downloaded and re-evaluated independently (CPU, fp32, 20 k tokens per language) and reproduce the same ordering: ru 1.022 against base 1.519, en 1.337 against 1.124, zh 4.053 against 3.393.
Russian landed past the target (1.123 against a 1.40 gate). English and Chinese regressed 21–24% instead of the ≤10% the recipe aimed for. a 25% replay mix is too thin at 0.36 B when the target language is tokenised this badly. A second pass with a 50/25/25 mix at lr 5e-5 was started, got through ~50 M of a planned 200 M tokens, and changed nothing measurable on English (1.337 → 1.337 on the same eval), so it is not published. Treat v1 as Russian-first, with working but measurably weaker English and Chinese.
Why the tokenizer shapes the recipe
The base vocabulary is a distilled 65 k set with almost no Cyrillic merges, and it is byte-level: the
vocabulary stores UTF-8 bytes remapped to latin-1, so convert_ids_to_tokens prints С where the text says
С. That is a display artifact; decode returns the word. The count is what matters:
| Word | Characters | Tokens | Pieces |
|---|---|---|---|
Спасибо |
7 | 6 | С · п · ас · и · б · о |
привет |
6 | 3 | пр · ив · ет |
покупать |
8 | 4 | п · ок · уп · ать |
Ёжик |
4 | 4 | Ё lands in two separate byte tokens |
Because the vocabulary is byte-level, a token can end in the middle of a character: in Ёжик and ЩУКА the
uppercase letters are cut into single bytes. Decoding the whole sequence is still exact, but a streaming client
must hold an incomplete UTF-8 sequence back instead of printing it. llama.cpp and transformers buffer it for
you; a hand-rolled decoder has to do the same or the output shows replacement characters.
| Tokenizer | RU chars/token | RU tokens per word | EN chars/token |
|---|---|---|---|
| MNN-Pocket / Qwen3-distilled (65,536) | 1.75–1.85 (2.08 on dialogue text) | ≈3.3 | 3.78 |
| +8,192 Cyrillic merges (73,728) | 3.10 | ≈1.8 | — |
| +16,384 Cyrillic merges (81,920) | 3.39 | ≈1.6 | — |
| ruGPT3-small (50 k, Russian BPE) | 4.2 | ≈1.3 | — |
Consequences that shaped the plan:
- the same 1.2 B-token budget buys
2.2 B Russian characters (340 M words), roughly 2.2× less text than a Russian-native tokenizer would fit; - on a phone one suggested Russian word costs ~3 decode steps instead of ~1, which matters for a keyboard latency budget;
- vocabulary surgery was measured but kept out of v1, so v1 stays tokenizer-compatible with the base and drops
into the existing MNN / GGUF toolchain. An extended-vocabulary artefact (
model_ext, 73,728 rows, embeddings initialised as the mean of their child tokens) exists in the private run repo but is not part of this release.
Recipe
- Full fine-tune from
MNN-Pocket-0.3B-Base, fp32 master weights with fp16 autocast. - Sequence length 1024, random windows over a packed
uint16token stream,<|endoftext|>between documents. - 32,768 tokens per optimizer step (micro-batch 4 × 1024, gradient accumulation 8).
- AdamW, β = (0.9, 0.95), weight decay 0.1, gradient clip 1.0, lr 2e-4 with 1% linear warmup and cosine decay.
- One epoch over 1.2 B tokens = 36,621 steps.
- Checkpoint every 500 steps to a private HF repo; training auto-resumes from the last checkpoint after a session restart.
Data
All sources are public Hugging Face datasets. * marks the validation split: the first 100 k tokens of each
stream are held out before training starts, so validation text is never seen.
| Language | Dataset | Config | Tokens | Share |
|---|---|---|---|---|
| ru | HuggingFaceFW/fineweb-2 |
rus_Cyrl |
0.90 B (100 k held out*) | 75% |
| en | HuggingFaceFW/fineweb |
sample-100BT |
0.204 B (100 k held out*) | 17% |
| zh | HuggingFaceFW/fineweb-2 |
cmn_Hani |
0.096 B (100 k held out*) | 8% |
Licences: FineWeb / FineWeb-2 are ODC-BY 1.0. No scraped Telegram dumps or other unlicensed chat corpora were used, so the resulting weights stay publishable.
Builds
| Build | Size | Download | Note |
|---|---|---|---|
| Q8_0 | 310 MB | MNN-Pocket-0.3B-RU-Q8_0.gguf |
near-lossless, for desktop |
| Q4_K_M | 223 MB | MNN-Pocket-0.3B-RU-Q4_K_M.gguf |
the size to ship on a phone |
| MNN INT4 | 165 MB | mnn/MNN-Pocket-0.3B-RU-INT4 | MNN runtime, Android |
Both files sit under gguf/ with the quant tag in the name, which is what llama.cpp matches on:
llama-cli -hf Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M -p "Сегодня я" -n 40
Converted with llama.cpp convert_hf_to_gguf.py (f16) and quantised with llama-quantize. Measured on a
16-thread x86 CPU, no GPU involved:
| Build | Prompt processing | Generation |
|---|---|---|
| Q4_K_M | ~410 tok/s | ~130 tok/s |
| Q8_0 | ~525 tok/s | ~99 tok/s |
Phone figures will be several times lower; these are desktop-CPU numbers.
The MNN build runs through MNN's own runtime. Build llm_demo from the MNN repository with
-DMNN_BUILD_LLM=ON, then point it at the folder:
cd mnn/MNN-Pocket-0.3B-RU-INT4 && llm_demo config.json prompt.txt
165 MB on disk, ~354 tok/s prefill and ~77 tok/s decode on 12 CPU threads here. llm_config.json carries no
chat template on purpose: this checkpoint continues the prompt, so the runtime should not wrap it in a dialogue
format.
Two conversion quirks, both already fixed in this repository's tokenizer_config.json.
- the base pre-tokenizer does not hash-match in current llama.cpp, so the Qwen pre-tokenizer has to be pinned
by hand (
qwen2); extra_special_tokensmust not be a list, or transformers v4 refuses to load the tokenizer.
Reproduce
Everything below runs on CPU. The numbers in this card came from these paths.
# bits/char, ppl and top-k against the base, 20k tokens per language
python bench/eval_bpc.py --model Rahspide/MNN-Pocket-0.3B-RU --base taobao-mnn/MNN-Pocket-0.3B-Base \
--dataset HuggingFaceFW/fineweb-2 --config rus_Cyrl --tokens 20000
# throughput and a smoke generation on the quantised build
LLAMA_CLI=/path/to/llama-cli bash bench/bench_cpu.sh gguf/MNN-Pocket-0.3B-RU-Q4_K_M.gguf
bench/eval_bpc.py reports the same three metrics as the tables above (ppl, bits/char, top-1/top-5) and exits
non-zero when the model loses more than a given --max-bpc-regression against the base, so it can run as a
regression gate in CI. bench/bench_cpu.sh prints prompt and generation tok/s and checks that generation stops
at <|endoftext|>.
Intended use
- On-device next-word and short-phrase suggestion in a keyboard or IME, Russian first, English and Chinese from the same checkpoint (a keyboard can pick the language from the current word or the layout).
- Text completion, prefix continuation and autocomplete for Russian anywhere a ~220 MB quantised model has to run locally: chat composers, note apps, search fields, terminal prompts.
- Any pipeline that needs a small causal LM fluent in Russian that can still read English and Chinese, for example tagging, short rewriting suggestions, or generating Russian seed text.
Not intended for: instruction following, factual question answering, code, long-form reasoning, or translation. This is a 0.36 B model trained for 1.2 B tokens; its knowledge is narrow by construction. The language mix is a deliberate trade: Russian is the target, English and Chinese are kept from degrading, neither is improved.
Limitations
- Russian is tokenised near character level (see above): slower decoding and a larger effective cost per Russian word than the same model pays for English.
- Token boundaries do not follow character boundaries. Rare and uppercase Cyrillic letters are split into
single bytes, so a streaming decoder must buffer partial UTF-8 sequences;
llama.cppandtransformersalready do this. - Web text only. Register is mostly written/informal blog Russian; no dialogue corpora, no post-training.
- Capacity is 0.36 B. Expect weak facts, weak arithmetic, and drift on long generations.
- English and Chinese regressed 21–24% against the base. The 25% replay mix limits the damage; it does not remove it.
- The ChatML template from the base is inherited but untrained here. Do not use this checkpoint in chat mode.
Releases
| Date | Version | What changed |
|---|---|---|
| 2026-11-10 | v1.0 | 1.2 B-token continued pretraining released: bf16 weights, GGUF Q8_0 and Q4_K_M, measured ru/en/zh bits-per-char |
| 2026-11-11 | v1.1 | MNN INT4 build for the MNN runtime: 165 MB, ~77 tok/s decode on 12 CPU threads |
| 2026-11-10 | v2.0 (sister) | Assistant checkpoint released: 50 M-token SFT on top of v1, weights and GGUF |
Licence and attribution
Weights: Apache-2.0, inherited from the base model. Data: ODC-BY 1.0 (FineWeb, FineWeb-2). If you use this model, credit the base release:
@misc{mnn_pocket_03b,
title = {MNN-Pocket-0.3B},
author = {Taobao MNN team},
year = {2026},
url = {https://huggingface.co/taobao-mnn/MNN-Pocket-0.3B}
}
- Downloads last month
- 624





Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp# Start a local OpenAI-compatible server: llama serve -hf Rahspide/MNN-Pocket-0.3B-RU:Q4_K_M