AwaleSagar commited on
Commit
8579c16
·
verified ·
1 Parent(s): 54b5507

Release gpio-llm-nano-rpi5 (GPIO-LLM v0.1.0)

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ gpio_llm_bpe_12k.gltk filter=lfs diff=lfs merge=lfs -text
37
+ nano.gllm filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: cc-by-4.0
3
+ language:
4
+ - en
5
+ library_name: transformers
6
+ pipeline_tag: text-generation
7
+ datasets:
8
+ - AwaleSagar/gpio-llm-rpi5-actions
9
+ - HuggingFaceTB/smollm-corpus
10
+ tags:
11
+ - raspberry-pi
12
+ - gpio
13
+ - embedded
14
+ - structured-output
15
+ - json
16
+ - llama
17
+ - tiny
18
+ model-index:
19
+ - name: gpio-llm-nano-rpi5
20
+ results:
21
+ - task:
22
+ type: text-generation
23
+ name: English GPIO request to JSON action
24
+ dataset:
25
+ name: gpio-llm-rpi5-actions (eval, 26,297 rows)
26
+ type: AwaleSagar/gpio-llm-rpi5-actions
27
+ config: gpio_actions_v2
28
+ split: eval
29
+ metrics:
30
+ - name: Exact match, PyTorch fp32 greedy
31
+ type: exact_match
32
+ value: 93.61
33
+ - name: Valid JSON, unconstrained
34
+ type: accuracy
35
+ value: 99.98
36
+ - task:
37
+ type: text-generation
38
+ name: English GPIO request to JSON action
39
+ dataset:
40
+ name: gpio-llm-rpi5-actions (eval_core, 5,083 rows)
41
+ type: AwaleSagar/gpio-llm-rpi5-actions
42
+ config: gpio_actions_v2
43
+ split: eval_core
44
+ metrics:
45
+ - name: Exact match, PyTorch fp32 greedy
46
+ type: exact_match
47
+ value: 91.82
48
+ - name: Exact match, int8 C engine with grammar
49
+ type: exact_match
50
+ value: 91.72
51
+ - name: Valid JSON, int8 C engine with grammar
52
+ type: accuracy
53
+ value: 100.00
54
+ ---
55
+
56
+ # gpio-llm-nano-rpi5
57
+
58
+ A 4.96M-parameter Llama-style model, trained from scratch, that turns one English request for a
59
+ Raspberry Pi 5 GPIO header into one JSON action:
60
+
61
+ ```
62
+ User: turn on the LED on GPIO 17
63
+ Assistant: {"action":"gpio_write","pin":17,"value":"HIGH"}
64
+ ```
65
+
66
+ This is the middle size, and our candidate for the single-core Pi Zero / Pi 1 boards. We have not measured it on those boards yet; the numbers below are from a Pi Zero 2 W. It is part of [GPIO-LLM](https://github.com/AwaleSagar/gpio-llm): the code, the C inference engine and the training scripts are on
67
+ GitHub, and the data is [AwaleSagar/gpio-llm-rpi5-actions](https://huggingface.co/datasets/AwaleSagar/gpio-llm-rpi5-actions). The other sizes are
68
+ [gpio-llm-pico-rpi5](https://huggingface.co/AwaleSagar/gpio-llm-pico-rpi5), [gpio-llm-base-rpi5](https://huggingface.co/AwaleSagar/gpio-llm-base-rpi5).
69
+
70
+ > ⚠️ The model is not a safety layer. It picks an action; a deterministic validator must check every action
71
+ > against the board's rules before anything touches a pin. Before the validator, 4.11% of the
72
+ > refusal or clarification cases in `eval` still come out as an executable action.
73
+
74
+ ## Use it
75
+
76
+ **On a Raspberry Pi, with the C engine** (no Python, no ML framework; int8 weights):
77
+
78
+ ```bash
79
+ git clone https://github.com/AwaleSagar/gpio-llm && make -C gpio-llm/engine
80
+ cd gpio-llm/engine
81
+ for f in nano.gllm gpio_llm_bpe_12k.gltk grammar_v2.txt; do
82
+ curl -LO https://huggingface.co/AwaleSagar/gpio-llm-nano-rpi5/resolve/main/$f
83
+ done
84
+ build/gpiollm -m nano.gllm -t gpio_llm_bpe_12k.gltk -g grammar_v2.txt "turn on the LED on GPIO 17"
85
+ build/gpiollm -m nano.gllm -t gpio_llm_bpe_12k.gltk -g grammar_v2.txt \
86
+ --context '{"device_mappings":{"fan":23}}' "switch the fan off"
87
+ ```
88
+
89
+ The engine decodes under a grammar built from the training labels, so its output is always one of the JSON
90
+ shapes the dataset uses.
91
+
92
+ **With transformers** (fp32, unconstrained greedy decoding):
93
+
94
+ ```python
95
+ from transformers import AutoModelForCausalLM, AutoTokenizer
96
+
97
+ repo = "AwaleSagar/gpio-llm-nano-rpi5"
98
+ tok = AutoTokenizer.from_pretrained(repo)
99
+ model = AutoModelForCausalLM.from_pretrained(repo)
100
+ prompt = "User: turn on the LED on GPIO 17\nAssistant:"
101
+ ids = tok(prompt, return_tensors="pt").input_ids
102
+ out = model.generate(ids, max_new_tokens=200, do_sample=False)
103
+ print(tok.decode(out[0, ids.shape[1]:], skip_special_tokens=True).strip())
104
+ ```
105
+
106
+ **Prompt format.** `User: <request>\nAssistant:`, optionally preceded by one context line such as
107
+ `Context: {"device_mappings":{"red_led":16}}\n` or `Context: {"available_pins":[16,17,18,25]}\n`. The answer
108
+ starts with a space and ends with `<|endoftext|>`. Multi-turn clarification follows the dataset format
109
+ (`...\nAssistant: <question>\nUser: <answer>\nAssistant:`).
110
+
111
+ ## Model
112
+
113
+ | | |
114
+ |---|---|
115
+ | Architecture | `LlamaForCausalLM`: 6 layers, d_model 192, 6 heads (head_dim 32), SwiGLU FFN 512, RoPE θ = 10000, RMSNorm ε = 1e-05, tied embeddings |
116
+ | Parameters | 4,960,704 |
117
+ | Vocabulary / context | 12,000 (byte-level BPE `gpio_llm_bpe_12k`, from the dataset repo) / 256 tokens |
118
+ | Weights | `model.safetensors` (fp32); `nano.gllm`: int8 Q8_0, groups of 32, for the C engine |
119
+
120
+ ## Training
121
+
122
+ Both stages ran on one rented RTX 4090 (24 GB), PyTorch 2.11 + CUDA 12.8, transformers 5.17.
123
+
124
+ | Stage | Data | Steps × batch | LR | Result | Time |
125
+ |---|---|---|---|---|---|
126
+ | Pretraining | 550M tokens of fineweb-edu-dedup (SmolLM corpus), 1 epoch | 8,392 × 65,536 tokens | 0.003, cosine, bf16 | val loss 3.6253 (perplexity 37.5) on 0.5M held-out tokens | 10.4 min |
127
+ | SFT | all 1,678,821 v2 train rows, 2 epochs; loss on the answer tokens only; ~2% English replay | 13,116 × 256 rows | 0.002, cosine | eval_core answer-token loss 0.0224 | 9.3 min |
128
+
129
+ The pretraining learning rate came from a sweep on the nano shape at 55M tokens (lr → val loss): 0.001 → 4.5915, 0.002 → 4.2903, 0.003 → 4.1836, 0.005 → 4.1985.
130
+ Logs are in `training/`.
131
+
132
+ ## Evaluation
133
+
134
+ Exact match compares canonical JSON (same object, key order ignored) with the label. `eval` has 26,297 rows from
135
+ 132 phrasing templates that never appear in training; `eval_core` is a 5,083-row stratified subset.
136
+
137
+ | Setup | Split | Exact match | Valid JSON | Unsafe execute* |
138
+ |---|---|---|---|---|
139
+ | PyTorch fp32, greedy | eval | 93.61% | 99.98% | 4.11% |
140
+ | PyTorch fp32, greedy | eval_core | 91.82% | 99.94% | 4.66% |
141
+ | C engine int8, no grammar | eval_core | 91.70% | 99.94% | 4.66% |
142
+ | C engine int8, grammar | eval_core | 91.72% | 100.00% | 4.82% |
143
+
144
+ \* Share of the refusal/clarification rows (1,845 in eval_core) where the model produced an
145
+ executable action instead. This is measured before any validator.
146
+
147
+ Latency with the C engine and the grammar, on all 5,083 eval_core requests from raw text (tokenizer included), 4 threads:
148
+
149
+ | Device | p50 | p95 |
150
+ |---|---|---|
151
+ | Raspberry Pi Zero 2 W, 64-bit Raspberry Pi OS, no heatsink (throttled at ~81 °C) | 132 ms | 280 ms |
152
+ | Apple M5 laptop | 2.7 ms | 5.0 ms |
153
+
154
+ The Pi's outputs were byte-identical to the Mac's on all 5,083 rows. The int8 engine's greedy answers matched
155
+ fp32 PyTorch on 200/200 sampled rows (minimum next-token logit cosine 0.99983).
156
+
157
+ ## Limitations
158
+
159
+ - **Pi 5 labels only.** The v2 data has no board field, so the labels follow the Pi 5 (RP1) rules, e.g.
160
+ per-pin drive strength. On older boards, board-specific cases must be caught by the validator.
161
+ - **Synthetic English requests.** They come from templates, a rule-based generator and (v1) model rewrites.
162
+ Real users will phrase things in ways the model has not seen.
163
+ - **Scope.** Digital I/O, PWM, pulses, waits, sequences, errors and clarifications only. There are no bus
164
+ transactions (I2C/SPI/UART data), and the context is 256 tokens.
165
+
166
+ ## Files
167
+
168
+ | File | What it is |
169
+ |---|---|
170
+ | `model.safetensors`, `config.json`, `generation_config.json` | fp32 transformers checkpoint |
171
+ | `tokenizer.json`, `tokenizer_config.json` | the dataset's `gpio_llm_bpe_12k` tokenizer |
172
+ | `nano.gllm` | int8 weights for the C engine |
173
+ | `gpio_llm_bpe_12k.gltk`, `grammar_v2.txt` | tokenizer and output grammar for the C engine |
174
+ | `training/` | training logs, LR sweep, eval summaries (JSON) |
175
+
176
+ ## Licence and attribution
177
+
178
+ The weights are released under **CC-BY-4.0**; the code on GitHub is Apache-2.0. The training data carries
179
+ its own terms:
180
+ - the fine-tuning data, [AwaleSagar/gpio-llm-rpi5-actions](https://huggingface.co/datasets/AwaleSagar/gpio-llm-rpi5-actions), is CC-BY-4.0
181
+ - its knowledge-base scenes are CC BY-SA 4.0
182
+ - the user wording in its v1 `teacher_*` rows was generated with third-party models, so check those
183
+ providers' terms on using model outputs
184
+ - the pretraining text is [fineweb-edu-dedup](https://huggingface.co/datasets/HuggingFaceTB/smollm-corpus) (ODC-By 1.0)
config.json ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "LlamaForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "bos_token_id": 0,
8
+ "dtype": "float32",
9
+ "eos_token_id": 0,
10
+ "head_dim": 32,
11
+ "hidden_act": "silu",
12
+ "hidden_size": 192,
13
+ "initializer_range": 0.02,
14
+ "intermediate_size": 512,
15
+ "max_position_embeddings": 256,
16
+ "mlp_bias": false,
17
+ "model_type": "llama",
18
+ "num_attention_heads": 6,
19
+ "num_hidden_layers": 6,
20
+ "num_key_value_heads": 6,
21
+ "pad_token_id": 1,
22
+ "pretraining_tp": 1,
23
+ "rms_norm_eps": 1e-05,
24
+ "rope_parameters": {
25
+ "rope_theta": 10000.0,
26
+ "rope_type": "default"
27
+ },
28
+ "tie_word_embeddings": true,
29
+ "transformers_version": "5.17.0",
30
+ "use_cache": true,
31
+ "vocab_size": 12000
32
+ }
generation_config.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "bos_token_id": 0,
4
+ "eos_token_id": 0,
5
+ "output_attentions": false,
6
+ "output_hidden_states": false,
7
+ "pad_token_id": 1,
8
+ "transformers_version": "5.17.0",
9
+ "use_cache": true
10
+ }
gpio_llm_bpe_12k.gltk ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ee3dbcfb71e6d7354588dc01cf21e1a69ac78df7279447d66be545ef866cada8
3
+ size 237021
grammar_v2.txt ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # gpiollm output grammar, built by train/build_grammar.py from 1,678,821 v2 train targets
2
+ CTX op 1
3
+ CTX params@op:gpio_mode 0
4
+ CTX params@op:gpio_pwm 0
5
+ CTX params@root:ask_clarification 0
6
+ CTX params@root:gpio_mode 0
7
+ CTX params@root:gpio_pwm 0
8
+ CTX params@root:gpio_read 0
9
+ CTX params@root:gpio_write 0
10
+ CTX params@root:report_error 0
11
+ CTX root 1
12
+ ROOT root
13
+ SEQ op gpio_mode action pin mode
14
+ SEQ op gpio_mode action pin mode parameters
15
+ SEQ op gpio_pulse action pin value duration_ms
16
+ SEQ op gpio_pwm action pin duty_cycle parameters
17
+ SEQ op gpio_read action pin
18
+ SEQ op gpio_write action pin value
19
+ SEQ op wait action duration_ms
20
+ SEQ params@op:gpio_mode - drive_strength_ma
21
+ SEQ params@op:gpio_mode - pull
22
+ SEQ params@op:gpio_pwm - pwm_type
23
+ SEQ params@root:ask_clarification - reason
24
+ SEQ params@root:gpio_mode - drive_strength_ma
25
+ SEQ params@root:gpio_mode - function
26
+ SEQ params@root:gpio_mode - header_pin
27
+ SEQ params@root:gpio_mode - pull
28
+ SEQ params@root:gpio_pwm - pwm_type
29
+ SEQ params@root:gpio_pwm - pwm_type frequency_hz
30
+ SEQ params@root:gpio_read - header_pin
31
+ SEQ params@root:gpio_write - header_pin
32
+ SEQ params@root:report_error - reason
33
+ SEQ params@root:report_error - reason header_pin
34
+ SEQ params@root:report_error - reason requested
35
+ SEQ params@root:report_error - reason requested drive_strength_ma
36
+ SEQ params@root:report_error - reason requested header_pin
37
+ SEQ root ask_clarification action pin parameters
38
+ SEQ root gpio_mode action pin mode
39
+ SEQ root gpio_mode action pin mode parameters
40
+ SEQ root gpio_pulse action pin value duration_ms
41
+ SEQ root gpio_pwm action pin duty_cycle parameters
42
+ SEQ root gpio_read action pin
43
+ SEQ root gpio_read action pin parameters
44
+ SEQ root gpio_sequence action operations
45
+ SEQ root gpio_write action pin value
46
+ SEQ root gpio_write action pin value parameters
47
+ SEQ root report_error action pin parameters
48
+ SEQ root wait action duration_ms
49
+ VAL op - action s 0 0 -
50
+ STR op - action gpio_mode
51
+ STR op - action gpio_pulse
52
+ STR op - action gpio_pwm
53
+ STR op - action gpio_read
54
+ STR op - action gpio_write
55
+ STR op - action wait
56
+ VAL op gpio_mode mode s 0 0 -
57
+ STR op gpio_mode mode INPUT
58
+ STR op gpio_mode mode OUTPUT
59
+ VAL op gpio_mode parameters o 0 0 params@op:gpio_mode
60
+ VAL op gpio_mode pin n 3 0 -
61
+ VAL op gpio_pulse duration_ms n 6 0 -
62
+ VAL op gpio_pulse pin n 3 0 -
63
+ VAL op gpio_pulse value s 0 0 -
64
+ STR op gpio_pulse value HIGH
65
+ VAL op gpio_pwm duty_cycle nf 3 2 -
66
+ VAL op gpio_pwm parameters o 0 0 params@op:gpio_pwm
67
+ VAL op gpio_pwm pin n 3 0 -
68
+ VAL op gpio_read pin n 3 0 -
69
+ VAL op gpio_write pin n 3 0 -
70
+ VAL op gpio_write value s 0 0 -
71
+ STR op gpio_write value HIGH
72
+ STR op gpio_write value LOW
73
+ VAL op wait duration_ms n 6 0 -
74
+ VAL params@op:gpio_mode - drive_strength_ma n 3 0 -
75
+ VAL params@op:gpio_mode - pull s 0 0 -
76
+ STR params@op:gpio_mode - pull DOWN
77
+ STR params@op:gpio_mode - pull UP
78
+ VAL params@op:gpio_pwm - pwm_type s 0 0 -
79
+ STR params@op:gpio_pwm - pwm_type hardware
80
+ STR params@op:gpio_pwm - pwm_type software
81
+ VAL params@root:ask_clarification - reason s 0 0 -
82
+ STR params@root:ask_clarification - reason ambiguous_device
83
+ STR params@root:ask_clarification - reason ambiguous_value
84
+ STR params@root:ask_clarification - reason conflicting_instructions
85
+ STR params@root:ask_clarification - reason missing_duration
86
+ STR params@root:ask_clarification - reason missing_duty_cycle
87
+ STR params@root:ask_clarification - reason missing_pin
88
+ STR params@root:ask_clarification - reason missing_value
89
+ STR params@root:ask_clarification - reason unknown_current_state
90
+ VAL params@root:gpio_mode - drive_strength_ma n 3 0 -
91
+ VAL params@root:gpio_mode - function s 0 0 -
92
+ STR params@root:gpio_mode - function I2C1_SCL
93
+ STR params@root:gpio_mode - function I2C1_SDA
94
+ STR params@root:gpio_mode - function SPI0_CE0
95
+ STR params@root:gpio_mode - function SPI0_CE1
96
+ STR params@root:gpio_mode - function SPI0_MISO
97
+ STR params@root:gpio_mode - function SPI0_MOSI
98
+ STR params@root:gpio_mode - function SPI0_SCLK
99
+ STR params@root:gpio_mode - function SPI1_CE0
100
+ STR params@root:gpio_mode - function SPI1_CE1
101
+ STR params@root:gpio_mode - function SPI1_CE2
102
+ STR params@root:gpio_mode - function SPI1_MISO
103
+ STR params@root:gpio_mode - function SPI1_MOSI
104
+ STR params@root:gpio_mode - function SPI1_SCLK
105
+ STR params@root:gpio_mode - function UART0_RX
106
+ STR params@root:gpio_mode - function UART0_TX
107
+ VAL params@root:gpio_mode - header_pin n 3 0 -
108
+ VAL params@root:gpio_mode - pull s 0 0 -
109
+ STR params@root:gpio_mode - pull DOWN
110
+ STR params@root:gpio_mode - pull NONE
111
+ STR params@root:gpio_mode - pull UP
112
+ VAL params@root:gpio_pwm - frequency_hz n 6 0 -
113
+ VAL params@root:gpio_pwm - pwm_type s 0 0 -
114
+ STR params@root:gpio_pwm - pwm_type hardware
115
+ STR params@root:gpio_pwm - pwm_type software
116
+ VAL params@root:gpio_read - header_pin n 3 0 -
117
+ VAL params@root:gpio_write - header_pin n 3 0 -
118
+ VAL params@root:report_error - drive_strength_ma n 3 0 -
119
+ VAL params@root:report_error - header_pin n 3 0 -
120
+ VAL params@root:report_error - reason s 0 0 -
121
+ STR params@root:report_error - reason invalid_gpio
122
+ STR params@root:report_error - reason invalid_parameter
123
+ STR params@root:report_error - reason no_hardware_action
124
+ STR params@root:report_error - reason not_a_gpio
125
+ STR params@root:report_error - reason pin_not_available
126
+ STR params@root:report_error - reason reserved_gpio
127
+ STR params@root:report_error - reason unsafe_current
128
+ STR params@root:report_error - reason unsafe_direct_drive
129
+ STR params@root:report_error - reason unsafe_short_circuit
130
+ STR params@root:report_error - reason unsafe_voltage
131
+ STR params@root:report_error - reason unsupported_function
132
+ STR params@root:report_error - reason unsupported_operation
133
+ VAL params@root:report_error - requested s 0 0 -
134
+ STR params@root:report_error - requested analog_input
135
+ STR params@root:report_error - requested drive_strength
136
+ STR params@root:report_error - requested duration
137
+ STR params@root:report_error - requested duty_cycle
138
+ STR params@root:report_error - requested frequency
139
+ STR params@root:report_error - requested function_conflict
140
+ STR params@root:report_error - requested hardware_pwm
141
+ STR params@root:report_error - requested i2c
142
+ STR params@root:report_error - requested i2c_scl
143
+ STR params@root:report_error - requested i2c_sda
144
+ STR params@root:report_error - requested led_resistor
145
+ STR params@root:report_error - requested load_current
146
+ STR params@root:report_error - requested output_voltage
147
+ STR params@root:report_error - requested pull_down
148
+ STR params@root:report_error - requested pull_none
149
+ STR params@root:report_error - requested spi
150
+ STR params@root:report_error - requested spi_sclk
151
+ STR params@root:report_error - requested uart_rx
152
+ STR params@root:report_error - requested uart_tx
153
+ VAL root - action s 0 0 -
154
+ STR root - action ask_clarification
155
+ STR root - action gpio_mode
156
+ STR root - action gpio_pulse
157
+ STR root - action gpio_pwm
158
+ STR root - action gpio_read
159
+ STR root - action gpio_sequence
160
+ STR root - action gpio_write
161
+ STR root - action report_error
162
+ STR root - action wait
163
+ VAL root ask_clarification parameters o 0 0 params@root:ask_clarification
164
+ VAL root ask_clarification pin z 0 0 -
165
+ VAL root gpio_mode mode s 0 0 -
166
+ STR root gpio_mode mode ALT
167
+ STR root gpio_mode mode INPUT
168
+ STR root gpio_mode mode OUTPUT
169
+ VAL root gpio_mode parameters o 0 0 params@root:gpio_mode
170
+ VAL root gpio_mode pin n 3 0 -
171
+ VAL root gpio_pulse duration_ms n 7 0 -
172
+ VAL root gpio_pulse pin n 3 0 -
173
+ VAL root gpio_pulse value s 0 0 -
174
+ STR root gpio_pulse value HIGH
175
+ STR root gpio_pulse value LOW
176
+ VAL root gpio_pwm duty_cycle nf 4 2 -
177
+ VAL root gpio_pwm parameters o 0 0 params@root:gpio_pwm
178
+ VAL root gpio_pwm pin n 3 0 -
179
+ VAL root gpio_read parameters o 0 0 params@root:gpio_read
180
+ VAL root gpio_read pin n 3 0 -
181
+ VAL root gpio_sequence operations a 0 0 op
182
+ VAL root gpio_write parameters o 0 0 params@root:gpio_write
183
+ VAL root gpio_write pin n 3 0 -
184
+ VAL root gpio_write value s 0 0 -
185
+ STR root gpio_write value HIGH
186
+ STR root gpio_write value LOW
187
+ VAL root report_error parameters o 0 0 params@root:report_error
188
+ VAL root report_error pin nmz 5 0 -
189
+ VAL root wait duration_ms n 7 0 -
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:258dfc8e3da3593719f52dec651dffdfe5e03d10d02ab85083c69972735a3090
3
+ size 19848896
nano.gllm ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f19cae5941263bc2afbc1b145523c097098fbba851bc1b06baef7eaa897db288
3
+ size 5588032
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "tokenizer_class": "PreTrainedTokenizerFast",
3
+ "eos_token": "<|endoftext|>",
4
+ "bos_token": "<|endoftext|>",
5
+ "pad_token": "<|pad|>",
6
+ "model_max_length": 256,
7
+ "clean_up_tokenization_spaces": false
8
+ }
training/eval_c_engine_mac_constrained.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "file": "mac_nano_constrained.out",
3
+ "rows": 5083,
4
+ "exact": 0.9171748967145387,
5
+ "valid_json": 1.0,
6
+ "unsafe_execute": 0.048238482384823846,
7
+ "non_exec_rows": 1845,
8
+ "latency_ms_p50": 2.7,
9
+ "latency_ms_p95": 5.0,
10
+ "latency_ms_max": 19.3,
11
+ "per_action_exact": {
12
+ "ask_clarification": 0.8560606060606061,
13
+ "gpio_mode": 0.9637305699481865,
14
+ "gpio_pulse": 0.9755434782608695,
15
+ "gpio_pwm": 0.9965397923875432,
16
+ "gpio_read": 0.9877622377622378,
17
+ "gpio_sequence": 0.9046653144016227,
18
+ "gpio_write": 0.8296370967741935,
19
+ "report_error": 0.9139784946236559,
20
+ "wait": 1.0
21
+ }
22
+ }
training/eval_c_engine_mac_unconstrained.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "file": "mac_nano_unconstrained.out",
3
+ "rows": 5083,
4
+ "exact": 0.9169781625024592,
5
+ "valid_json": 0.9994097973637616,
6
+ "unsafe_execute": 0.046612466124661245,
7
+ "non_exec_rows": 1845,
8
+ "latency_ms_p50": 3.5,
9
+ "latency_ms_p95": 6.8,
10
+ "latency_ms_max": 25.9,
11
+ "per_action_exact": {
12
+ "ask_clarification": 0.8560606060606061,
13
+ "gpio_mode": 0.9637305699481865,
14
+ "gpio_pulse": 0.9755434782608695,
15
+ "gpio_pwm": 0.9965397923875432,
16
+ "gpio_read": 0.9877622377622378,
17
+ "gpio_sequence": 0.9046653144016227,
18
+ "gpio_write": 0.8296370967741935,
19
+ "report_error": 0.9133459835547122,
20
+ "wait": 1.0
21
+ }
22
+ }
training/eval_c_engine_pi_zero2w.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "file": "pi_nano_constrained.out",
3
+ "rows": 5083,
4
+ "exact": 0.9171748967145387,
5
+ "valid_json": 1.0,
6
+ "unsafe_execute": 0.048238482384823846,
7
+ "non_exec_rows": 1845,
8
+ "latency_ms_p50": 132.3,
9
+ "latency_ms_p95": 279.96,
10
+ "latency_ms_max": 1514.0,
11
+ "per_action_exact": {
12
+ "ask_clarification": 0.8560606060606061,
13
+ "gpio_mode": 0.9637305699481865,
14
+ "gpio_pulse": 0.9755434782608695,
15
+ "gpio_pwm": 0.9965397923875432,
16
+ "gpio_read": 0.9877622377622378,
17
+ "gpio_sequence": 0.9046653144016227,
18
+ "gpio_write": 0.8296370967741935,
19
+ "report_error": 0.9139784946236559,
20
+ "wait": 1.0
21
+ }
22
+ }
training/eval_pytorch_fp32_eval.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "exact": 0.9360763585199833,
3
+ "valid_json": 0.9997718370916835,
4
+ "action": 0.9620489029166825,
5
+ "unsafe_execute": 0.04111111111111111,
6
+ "model": "../runs/nano-sft/final",
7
+ "split": "eval",
8
+ "rows": 26297
9
+ }
training/eval_pytorch_fp32_eval_core.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "exact": 0.9181585677749361,
3
+ "valid_json": 0.9994097973637616,
4
+ "action": 0.9478654337989376,
5
+ "unsafe_execute": 0.046612466124661245,
6
+ "model": "../runs/nano-sft/final",
7
+ "split": "eval_core",
8
+ "rows": 5083
9
+ }
training/int8_vs_fp32_parity.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ wrote nano.gllm (re-export) (5.59 MB)
2
+ next-token logits: min cosine 0.99983, argmax agreement 200/200
3
+ greedy answers: int8 engine == fp32 PyTorch on 200/200 rows (100.0%; Phase 4 gate is 99.5%)
4
+ re-export is byte-identical
training/lr_sweep-nano-1e-3.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "args": {
3
+ "shape": "nano",
4
+ "tokens": 55000000,
5
+ "batch": 256,
6
+ "lr": 0.001,
7
+ "wd": 0.1,
8
+ "warmup": 100,
9
+ "min_lr_frac": 0.1,
10
+ "eval_every": 100000,
11
+ "max_minutes": 6.0,
12
+ "seed": 1234,
13
+ "out": "sweep-nano-1e-3",
14
+ "compile": true
15
+ },
16
+ "params": 4960704,
17
+ "log": [
18
+ {
19
+ "step": 838,
20
+ "train_loss": 4.611106872558594,
21
+ "val_loss": 4.59149022102356,
22
+ "minutes": 1.2885763804117838
23
+ }
24
+ ]
25
+ }
training/lr_sweep-nano-2e-3.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "args": {
3
+ "shape": "nano",
4
+ "tokens": 55000000,
5
+ "batch": 256,
6
+ "lr": 0.002,
7
+ "wd": 0.1,
8
+ "warmup": 100,
9
+ "min_lr_frac": 0.1,
10
+ "eval_every": 100000,
11
+ "max_minutes": 6.0,
12
+ "seed": 1234,
13
+ "out": "sweep-nano-2e-3",
14
+ "compile": true
15
+ },
16
+ "params": 4960704,
17
+ "log": [
18
+ {
19
+ "step": 838,
20
+ "train_loss": 4.3140764236450195,
21
+ "val_loss": 4.290324306488037,
22
+ "minutes": 1.0765070875485738
23
+ }
24
+ ]
25
+ }
training/lr_sweep-nano-3e-3.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "args": {
3
+ "shape": "nano",
4
+ "tokens": 55000000,
5
+ "batch": 256,
6
+ "lr": 0.003,
7
+ "wd": 0.1,
8
+ "warmup": 100,
9
+ "min_lr_frac": 0.1,
10
+ "eval_every": 100000,
11
+ "max_minutes": 6.0,
12
+ "seed": 1234,
13
+ "out": "sweep-nano-3e-3",
14
+ "compile": true
15
+ },
16
+ "params": 4960704,
17
+ "log": [
18
+ {
19
+ "step": 838,
20
+ "train_loss": 4.225688457489014,
21
+ "val_loss": 4.183564710617065,
22
+ "minutes": 1.0914083560307821
23
+ }
24
+ ]
25
+ }
training/lr_sweep-nano-5e-3.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "args": {
3
+ "shape": "nano",
4
+ "tokens": 55000000,
5
+ "batch": 256,
6
+ "lr": 0.005,
7
+ "wd": 0.1,
8
+ "warmup": 100,
9
+ "min_lr_frac": 0.1,
10
+ "eval_every": 100000,
11
+ "max_minutes": 6.0,
12
+ "seed": 1234,
13
+ "out": "sweep-nano-5e-3",
14
+ "compile": true
15
+ },
16
+ "params": 4960704,
17
+ "log": [
18
+ {
19
+ "step": 838,
20
+ "train_loss": 4.234477519989014,
21
+ "val_loss": 4.1984649181365965,
22
+ "minutes": 1.1979833285013834
23
+ }
24
+ ]
25
+ }
training/pretrain_log.json ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "args": {
3
+ "shape": "nano",
4
+ "tokens": 550000000,
5
+ "batch": 256,
6
+ "lr": 0.003,
7
+ "wd": 0.1,
8
+ "warmup": 100,
9
+ "min_lr_frac": 0.1,
10
+ "eval_every": 1000,
11
+ "max_minutes": 45.0,
12
+ "seed": 1234,
13
+ "out": "nano-pt",
14
+ "compile": true
15
+ },
16
+ "params": 4960704,
17
+ "log": [
18
+ {
19
+ "step": 1000,
20
+ "train_loss": 4.157930374145508,
21
+ "val_loss": 4.101281976699829,
22
+ "minutes": 1.265407105286916
23
+ },
24
+ {
25
+ "step": 2000,
26
+ "train_loss": 4.010364532470703,
27
+ "val_loss": 3.921313500404358,
28
+ "minutes": 2.4889028827349344
29
+ },
30
+ {
31
+ "step": 3000,
32
+ "train_loss": 3.8780674934387207,
33
+ "val_loss": 3.8422478675842284,
34
+ "minutes": 3.7334064563115437
35
+ },
36
+ {
37
+ "step": 4000,
38
+ "train_loss": 3.891343593597412,
39
+ "val_loss": 3.785443663597107,
40
+ "minutes": 4.978402447700501
41
+ },
42
+ {
43
+ "step": 5000,
44
+ "train_loss": 3.8154168128967285,
45
+ "val_loss": 3.730230283737183,
46
+ "minutes": 6.2154850920041405
47
+ },
48
+ {
49
+ "step": 6000,
50
+ "train_loss": 3.758894443511963,
51
+ "val_loss": 3.6891664028167725,
52
+ "minutes": 7.451739505926768
53
+ },
54
+ {
55
+ "step": 7000,
56
+ "train_loss": 3.7148094177246094,
57
+ "val_loss": 3.650411367416382,
58
+ "minutes": 8.679173755645753
59
+ },
60
+ {
61
+ "step": 8000,
62
+ "train_loss": 3.737409830093384,
63
+ "val_loss": 3.6295988082885744,
64
+ "minutes": 9.910523466269176
65
+ },
66
+ {
67
+ "step": 8391,
68
+ "train_loss": 3.695378065109253,
69
+ "val_loss": 3.625276494026184,
70
+ "minutes": 10.390244070688883
71
+ }
72
+ ]
73
+ }
training/sft_log.json ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "args": {
3
+ "init": "../runs/nano-pt/final",
4
+ "shape": "nano",
5
+ "train_rows": null,
6
+ "epochs": 2.0,
7
+ "batch": 256,
8
+ "lr": 0.002,
9
+ "wd": 0.1,
10
+ "warmup": 50,
11
+ "replay_every": 12,
12
+ "replay_batch": 4,
13
+ "eval_every": 1000,
14
+ "eval_rows": 1000,
15
+ "max_minutes": 50.0,
16
+ "seed": 1234,
17
+ "out": "nano-sft"
18
+ },
19
+ "log": [
20
+ {
21
+ "step": 1000,
22
+ "train_loss": 0.006621028296649456,
23
+ "eval_target_loss": 0.07434787717331105,
24
+ "minutes": 0.7496363361676533
25
+ },
26
+ {
27
+ "step": 2000,
28
+ "train_loss": 0.02178449183702469,
29
+ "eval_target_loss": 0.05123574915808273,
30
+ "minutes": 1.4465561429659526
31
+ },
32
+ {
33
+ "step": 3000,
34
+ "train_loss": 0.00805601105093956,
35
+ "eval_target_loss": 0.04877272646884206,
36
+ "minutes": 2.1609952886899313
37
+ },
38
+ {
39
+ "step": 4000,
40
+ "train_loss": 0.0015760211972519755,
41
+ "eval_target_loss": 0.0506566401789748,
42
+ "minutes": 2.850797164440155
43
+ },
44
+ {
45
+ "step": 5000,
46
+ "train_loss": 0.0027423014398664236,
47
+ "eval_target_loss": 0.04380449522909304,
48
+ "minutes": 3.5392218232154846
49
+ },
50
+ {
51
+ "step": 6000,
52
+ "train_loss": 0.001060945214703679,
53
+ "eval_target_loss": 0.0389024249297705,
54
+ "minutes": 4.238372592131297
55
+ },
56
+ {
57
+ "step": 7000,
58
+ "train_loss": 0.0005649410304613411,
59
+ "eval_target_loss": 0.03259135582334248,
60
+ "minutes": 4.983746925989787
61
+ },
62
+ {
63
+ "step": 8000,
64
+ "train_loss": 0.0010784538462758064,
65
+ "eval_target_loss": 0.028708800912080383,
66
+ "minutes": 5.700136307875315
67
+ },
68
+ {
69
+ "step": 9000,
70
+ "train_loss": 0.0004312685050535947,
71
+ "eval_target_loss": 0.02426343787667973,
72
+ "minutes": 6.410312342643738
73
+ },
74
+ {
75
+ "step": 10000,
76
+ "train_loss": 0.00011572329822229221,
77
+ "eval_target_loss": 0.02548710253615743,
78
+ "minutes": 7.112147303422292
79
+ },
80
+ {
81
+ "step": 11000,
82
+ "train_loss": 0.0005688337259925902,
83
+ "eval_target_loss": 0.02789109825700458,
84
+ "minutes": 7.8145731012026465
85
+ },
86
+ {
87
+ "step": 12000,
88
+ "train_loss": 6.69505971018225e-05,
89
+ "eval_target_loss": 0.0214684495689006,
90
+ "minutes": 8.530480217933654
91
+ },
92
+ {
93
+ "step": 13000,
94
+ "train_loss": 0.0004814007261302322,
95
+ "eval_target_loss": 0.02294556570453032,
96
+ "minutes": 9.222708662350973
97
+ },
98
+ {
99
+ "step": 13115,
100
+ "train_loss": 3.8525613490492105e-05,
101
+ "eval_target_loss": 0.022417631390016398,
102
+ "minutes": 9.301433749993642
103
+ }
104
+ ]
105
+ }