Text Generation
Transformers
Safetensors
English
llama
raspberry-pi
gpio
embedded
structured-output
json
tiny
Eval Results (legacy)
text-generation-inference
Instructions to use AwaleSagar/gpio-llm-base-rpi5 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use AwaleSagar/gpio-llm-base-rpi5 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="AwaleSagar/gpio-llm-base-rpi5")# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("AwaleSagar/gpio-llm-base-rpi5") model = AutoModelForCausalLM.from_pretrained("AwaleSagar/gpio-llm-base-rpi5", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use AwaleSagar/gpio-llm-base-rpi5 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "AwaleSagar/gpio-llm-base-rpi5" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "AwaleSagar/gpio-llm-base-rpi5", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/AwaleSagar/gpio-llm-base-rpi5
- SGLang
How to use AwaleSagar/gpio-llm-base-rpi5 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 "AwaleSagar/gpio-llm-base-rpi5" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "AwaleSagar/gpio-llm-base-rpi5", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'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 "AwaleSagar/gpio-llm-base-rpi5" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "AwaleSagar/gpio-llm-base-rpi5", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use AwaleSagar/gpio-llm-base-rpi5 with Docker Model Runner:
docker model run hf.co/AwaleSagar/gpio-llm-base-rpi5
| license: cc-by-4.0 | |
| language: | |
| - en | |
| library_name: transformers | |
| pipeline_tag: text-generation | |
| datasets: | |
| - AwaleSagar/gpio-llm-rpi5-actions | |
| - HuggingFaceTB/smollm-corpus | |
| tags: | |
| - raspberry-pi | |
| - gpio | |
| - embedded | |
| - structured-output | |
| - json | |
| - llama | |
| - tiny | |
| model-index: | |
| - name: gpio-llm-base-rpi5 | |
| results: | |
| - task: | |
| type: text-generation | |
| name: English GPIO request to JSON action | |
| dataset: | |
| name: gpio-llm-rpi5-actions (eval, 26,297 rows) | |
| type: AwaleSagar/gpio-llm-rpi5-actions | |
| config: gpio_actions_v2 | |
| split: eval | |
| metrics: | |
| - name: Exact match, PyTorch fp32 greedy | |
| type: exact_match | |
| value: 95.17 | |
| - name: Valid JSON, unconstrained | |
| type: accuracy | |
| value: 99.98 | |
| - task: | |
| type: text-generation | |
| name: English GPIO request to JSON action | |
| dataset: | |
| name: gpio-llm-rpi5-actions (eval_core, 5,083 rows) | |
| type: AwaleSagar/gpio-llm-rpi5-actions | |
| config: gpio_actions_v2 | |
| split: eval_core | |
| metrics: | |
| - name: Exact match, PyTorch fp32 greedy | |
| type: exact_match | |
| value: 93.47 | |
| - name: Exact match, int8 C engine with grammar | |
| type: exact_match | |
| value: 93.51 | |
| - name: Valid JSON, int8 C engine with grammar | |
| type: accuracy | |
| value: 100.00 | |
| # gpio-llm-base-rpi5 | |
| A 18.77M-parameter Llama-style model, trained from scratch, that turns one English request for a | |
| Raspberry Pi 5 GPIO header into one JSON action: | |
| ``` | |
| User: turn on the LED on GPIO 17 | |
| Assistant: {"action":"gpio_write","pin":17,"value":"HIGH"} | |
| ``` | |
| This is the largest and most accurate of the three sizes. It is part of [GPIO-LLM](https://github.com/AwaleSagar/gpio-llm): the code, the C inference engine and the training scripts are on | |
| GitHub, and the data is [AwaleSagar/gpio-llm-rpi5-actions](https://huggingface.co/datasets/AwaleSagar/gpio-llm-rpi5-actions). The other sizes are | |
| [gpio-llm-pico-rpi5](https://huggingface.co/AwaleSagar/gpio-llm-pico-rpi5), [gpio-llm-nano-rpi5](https://huggingface.co/AwaleSagar/gpio-llm-nano-rpi5). | |
| > ⚠️ The model is not a safety layer. It picks an action; a deterministic validator must check every action | |
| > against the board's rules before anything touches a pin. Before the validator, 0.96% of the | |
| > refusal or clarification cases in `eval` still come out as an executable action. | |
| ## Use it | |
| **On a Raspberry Pi, with the C engine** (no Python, no ML framework; int8 weights): | |
| ```bash | |
| git clone https://github.com/AwaleSagar/gpio-llm && make -C gpio-llm/engine | |
| cd gpio-llm/engine | |
| for f in base.gllm gpio_llm_bpe_12k.gltk grammar_v2.txt; do | |
| curl -LO https://huggingface.co/AwaleSagar/gpio-llm-base-rpi5/resolve/main/$f | |
| done | |
| build/gpiollm -m base.gllm -t gpio_llm_bpe_12k.gltk -g grammar_v2.txt "turn on the LED on GPIO 17" | |
| build/gpiollm -m base.gllm -t gpio_llm_bpe_12k.gltk -g grammar_v2.txt \ | |
| --context '{"device_mappings":{"fan":23}}' "switch the fan off" | |
| ``` | |
| The engine decodes under a grammar built from the training labels, so its output is always one of the JSON | |
| shapes the dataset uses. | |
| **With transformers** (fp32, unconstrained greedy decoding): | |
| ```python | |
| from transformers import AutoModelForCausalLM, AutoTokenizer | |
| repo = "AwaleSagar/gpio-llm-base-rpi5" | |
| tok = AutoTokenizer.from_pretrained(repo) | |
| model = AutoModelForCausalLM.from_pretrained(repo) | |
| prompt = "User: turn on the LED on GPIO 17\nAssistant:" | |
| ids = tok(prompt, return_tensors="pt").input_ids | |
| out = model.generate(ids, max_new_tokens=200, do_sample=False) | |
| print(tok.decode(out[0, ids.shape[1]:], skip_special_tokens=True).strip()) | |
| ``` | |
| **Prompt format.** `User: <request>\nAssistant:`, optionally preceded by one context line such as | |
| `Context: {"device_mappings":{"red_led":16}}\n` or `Context: {"available_pins":[16,17,18,25]}\n`. The answer | |
| starts with a space and ends with `<|endoftext|>`. Multi-turn clarification follows the dataset format | |
| (`...\nAssistant: <question>\nUser: <answer>\nAssistant:`). | |
| ## Model | |
| | | | | |
| |---|---| | |
| | Architecture | `LlamaForCausalLM`: 8 layers, d_model 384, 12 heads (head_dim 32), SwiGLU FFN 1024, RoPE θ = 10000, RMSNorm ε = 1e-05, tied embeddings | | |
| | Parameters | 18,770,304 | | |
| | Vocabulary / context | 12,000 (byte-level BPE `gpio_llm_bpe_12k`, from the dataset repo) / 256 tokens | | |
| | Weights | `model.safetensors` (fp32); `base.gllm`: int8 Q8_0, groups of 32, for the C engine | | |
| ## Training | |
| Both stages ran on one rented RTX 4090 (24 GB), PyTorch 2.11 + CUDA 12.8, transformers 5.17. | |
| | Stage | Data | Steps × batch | LR | Result | Time | | |
| |---|---|---|---|---|---| | |
| | Pretraining | 550M tokens of fineweb-edu-dedup (SmolLM corpus), 1 epoch | 8,392 × 65,536 tokens | 0.002, cosine, bf16 | val loss 3.2956 (perplexity 27.0) on 0.5M held-out tokens | 19.3 min | | |
| | SFT | all 1,678,821 v2 train rows, 2 epochs; loss on the answer tokens only; 4×256 English tokens replayed every 12 steps (~1.1% of loss tokens) | 13,116 × 256 rows | 0.001, cosine | eval_core answer-token loss 0.0201 | 13.5 min | | |
| The pretraining learning rate came from a sweep on the base shape at 55M tokens (lr → val loss): 0.0005 → 4.5519, 0.001 → 4.2294, 0.002 → 4.0577. | |
| Logs are in `training/`. | |
| ## Evaluation | |
| Exact match compares canonical JSON (same object, key order ignored) with the label. `eval` has 26,297 rows from | |
| 132 phrasing templates that never appear in training; `eval_core` is a 5,083-row stratified subset. | |
| | Setup | Split | Exact match | Valid JSON | Unsafe execute* | | |
| |---|---|---|---|---| | |
| | PyTorch fp32, greedy | eval | 95.17% | 99.98% | 0.96% | | |
| | PyTorch fp32, greedy | eval_core | 93.47% | 99.96% | 1.73% | | |
| | C engine int8, no grammar | eval_core | 93.51% | 99.96% | 1.73% | | |
| | C engine int8, grammar | eval_core | 93.51% | 100.00% | 1.84% | | |
| \* Share of the refusal/clarification rows (1,845 in eval_core) where the model produced an | |
| executable action instead. This is measured before any validator. | |
| Latency with the C engine and the grammar, on all 5,083 eval_core requests from raw text (tokenizer included), 4 threads: | |
| | Device | p50 | p95 | | |
| |---|---|---| | |
| | Raspberry Pi Zero 2 W, 64-bit Raspberry Pi OS, no heatsink (throttled at ~81 °C) | 498 ms | 1006 ms | | |
| | Apple M5 laptop | 11.7 ms | 21.2 ms | | |
| The Pi's outputs were byte-identical to the Mac's on all 5,083 rows. The int8 engine's greedy answers matched | |
| fp32 PyTorch on 200/200 sampled rows (minimum next-token logit cosine 0.99759). | |
| ## Limitations | |
| - **Pi 5 labels only.** The v2 data has no board field, so the labels follow the Pi 5 (RP1) rules, e.g. | |
| per-pin drive strength. On older boards, board-specific cases must be caught by the validator. | |
| - **Synthetic English requests.** They come from templates, a rule-based generator and (v1) model rewrites. | |
| Real users will phrase things in ways the model has not seen. | |
| - **Scope.** Digital I/O, PWM, pulses, waits, sequences, errors and clarifications only. There are no bus | |
| transactions (I2C/SPI/UART data), and the context is 256 tokens. | |
| ## Files | |
| | File | What it is | | |
| |---|---| | |
| | `model.safetensors`, `config.json`, `generation_config.json` | fp32 transformers checkpoint | | |
| | `tokenizer.json`, `tokenizer_config.json` | the dataset's `gpio_llm_bpe_12k` tokenizer | | |
| | `base.gllm` | int8 weights for the C engine | | |
| | `gpio_llm_bpe_12k.gltk`, `grammar_v2.txt` | tokenizer and output grammar for the C engine | | |
| | `training/` | training logs, LR sweep, eval summaries (JSON) | | |
| ## Licence and attribution | |
| The weights are released under **CC-BY-4.0**; the code on GitHub is Apache-2.0. The training data carries | |
| its own terms: | |
| - the fine-tuning data, [AwaleSagar/gpio-llm-rpi5-actions](https://huggingface.co/datasets/AwaleSagar/gpio-llm-rpi5-actions), is CC-BY-4.0 | |
| - its knowledge-base scenes are CC BY-SA 4.0 | |
| - the user wording in its v1 `teacher_*` rows was generated with third-party models, so check those | |
| providers' terms on using model outputs | |
| - the pretraining text is [fineweb-edu-dedup](https://huggingface.co/datasets/HuggingFaceTB/smollm-corpus) (ODC-By 1.0) | |