playforgecoding commited on
Commit
d6447a5
·
verified ·
1 Parent(s): 0c3fb4d

int8 export verified through transformers.js on the held-out lessons

Browse files
Files changed (1) hide show
  1. README.md +79 -46
README.md CHANGED
@@ -3,81 +3,114 @@ license: other
3
  license_name: lfm1.0
4
  license_link: LICENSE
5
  language:
6
- - en
7
  pipeline_tag: text-generation
8
- tags:
9
- - liquid
10
- - lfm2
11
- - edge
12
- - extraction
13
- - spelling-creator
14
  library_name: transformers.js
15
  base_model: playforgecoding/LFM2-1.2B-Extract-lesson
 
 
 
 
 
 
16
  ---
17
 
18
  # LFM2-1.2B-Extract, fine-tuned for Spelling Creator lesson documents (ONNX)
19
 
20
- The ONNX export of [playforgecoding/LFM2-1.2B-Extract-lesson](https://huggingface.co/playforgecoding/LFM2-1.2B-Extract-lesson) for [Transformers.js](https://huggingface.co/docs/transformers.js), made with the onnxruntime-genai model builder and laid out the way the onnx-community LFM2 files are.
 
 
 
 
21
 
22
  ## What it does
23
 
24
- Turns one section of a spelling lesson document, as a person might type it up or as this app's own Word export reads back as plain text, into the lesson's JSON: the passage paragraphs copied word for word, the spelling words, and every question with its printed answers and working-out. It is a fine-tune of [LiquidAI/LFM2-1.2B-Extract](https://huggingface.co/LiquidAI/LFM2-1.2B-Extract) for [Spelling Creator](https://github.com/Spelling-Creator/spelling-creator), a lesson builder for Spelling to Communicate (S2C), where lessons are read aloud to nonspeaking spellers.
25
-
26
- The stock Extract model handled this badly: it split paragraphs into sentences, invented answers for open questions, and often abandoned the schema. This fine-tune copies rather than invents.
27
-
28
- ## Training
29
-
30
- LoRA (rank 16, learning rate 2e-4, 3 epochs, 4096-token context) on 412 examples: the 13 published lessons on the Spelling Creator hub, each rendered in 7 document layouts (the app's Word export read as raw text, and six typed-up styles) and cut into sections, paired with the section's lesson JSON. 84 sections from the two newest lessons were held out. The data generator and the training notebook are in the repo under `packages/core/scripts/extract-eval/`.
31
-
32
- ## Results
33
-
34
- On a sample of 20 held-out sections spread across both held-out lessons and all layouts:
35
-
36
- | metric | value |
37
- | --- | ---: |
38
- | sections parsed as JSON | 95% |
39
- | spelling words exact | 85% |
40
- | question prompts found | 95% |
41
- | answers exact | 98% |
42
- | answers invented for open questions | 1 |
43
-
44
- For comparison, the stock model's answers were right about half the time on a tidy typed document and a quarter of the time on the Word export. Question types are not reliable from this or any small model; Spelling Creator derives the type from the answers and wording instead. The rule-based parser in the app still beats this model on every regular layout; the model is for documents the parser cannot read. The full write-up: [https://spellingcreator.org/docs/monorepo/document-import-experiment](https://spellingcreator.org/docs/monorepo/document-import-experiment).
45
-
46
- ## Prompt
47
-
48
- The system prompt is `Return data as a JSON object with the following schema:` followed by the JSON Schema of a section (`name`, `paragraphs`, `spellingWords`, `questions[{prompt, type, answers, steps}]`), and the user turn is the section's text. Greedy decoding.
49
 
50
  ## Files
51
 
52
- | file | for | note |
53
- | --- | --- | --- |
54
- | `onnx/model_q4f16.onnx` | WebGPU (`device: "webgpu"`, `dtype: "q4f16"`) | Verified: copies a real section faithfully in Chromium. The one to ship in a browser. |
55
- | `onnx/model_int8.onnx` | CPU: Node and the wasm backend (`dtype: "int8"`) | See the model's own card for whether this build passed the copy check. |
56
- | `onnx/model_q4.onnx` | CPU | Not faithful for this checkpoint: paraphrases instead of copying. Kept for reference. |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  ## Use
59
 
60
  ```javascript
61
  import { AutoModelForCausalLM, AutoTokenizer } from "@huggingface/transformers";
62
 
63
- const id = "playforgecoding/LFM2-1.2B-Extract-lesson-ONNX";
64
- const tokenizer = await AutoTokenizer.from_pretrained(id);
65
- const model = await AutoModelForCausalLM.from_pretrained(id, { dtype: "q4f16", device: "webgpu" });
 
 
 
 
66
  const inputs = tokenizer.apply_chat_template(
67
  [
68
- { role: "system", content: "Return data as a JSON object with the following schema:\n" + SCHEMA },
 
 
 
 
69
  { role: "user", content: sectionText },
70
  ],
71
  { add_generation_prompt: true, return_dict: true },
72
  );
73
- const output = await model.generate({ ...inputs, max_new_tokens: 1500, do_sample: false });
74
- console.log(tokenizer.batch_decode(output.slice(null, [inputs.input_ids.dims[1], null]), { skip_special_tokens: true })[0]);
 
 
 
 
 
 
 
 
75
  ```
76
 
77
  ## How it was converted
78
 
79
- `python -m onnxruntime_genai.models.builder -i merged -p int4 -e webgpu` (q4f16) and `-e cpu` builds, then `relayout-onnx.py` from the Spelling Creator repo: it renames the convolution caches to `past_conv.N`, makes the KV cache's head dimension concrete, moves the chat template into `tokenizer_config.json`, adds the `transformers.js_config` block, and puts the graphs under `onnx/`.
 
 
 
 
 
 
80
 
81
  ## Licence
82
 
83
- Derived from LFM2-1.2B-Extract and released under the same LFM Open License v1.0 (see LICENSE).
 
 
3
  license_name: lfm1.0
4
  license_link: LICENSE
5
  language:
6
+ - en
7
  pipeline_tag: text-generation
 
 
 
 
 
 
8
  library_name: transformers.js
9
  base_model: playforgecoding/LFM2-1.2B-Extract-lesson
10
+ tags:
11
+ - liquid
12
+ - lfm2
13
+ - edge
14
+ - extraction
15
+ - spelling-creator
16
  ---
17
 
18
  # LFM2-1.2B-Extract, fine-tuned for Spelling Creator lesson documents (ONNX)
19
 
20
+ The ONNX export of
21
+ [playforgecoding/LFM2-1.2B-Extract-lesson](https://huggingface.co/playforgecoding/LFM2-1.2B-Extract-lesson)
22
+ for [Transformers.js](https://huggingface.co/docs/transformers.js), made with
23
+ the onnxruntime-genai model builder and laid out the way the onnx-community
24
+ LFM2 files are.
25
 
26
  ## What it does
27
 
28
+ Turns one section of a spelling lesson document, as a person might type it up
29
+ or as the app's own Word export reads back as plain text, into the lesson's
30
+ JSON: the passage paragraphs copied word for word, the spelling words, and
31
+ every question with its printed answers and working-out. It is a fine-tune of
32
+ [LiquidAI/LFM2-1.2B-Extract](https://huggingface.co/LiquidAI/LFM2-1.2B-Extract)
33
+ for [Spelling Creator](https://github.com/Spelling-Creator/spelling-creator), a
34
+ lesson builder for Spelling to Communicate (S2C), where lessons are read aloud
35
+ to nonspeaking spellers. The training and the results are on the merged
36
+ model's card.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
  ## Files
39
 
40
+ | file | for | note |
41
+ | ----------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------- |
42
+ | `onnx/model_q4f16.onnx` | WebGPU (`device: "webgpu"`, `dtype: "q4f16"`) | Verified: copies a real section faithfully in Chromium. The one to ship in a browser. |
43
+ | `onnx/model_int8.onnx` | CPU: Node and the wasm backend (`dtype: "int8"`) | Verified through transformers.js on the held-out lessons: answers 96 to 100% exact on six of seven layouts (see below). The one to use on a CPU. |
44
+ | `onnx/model_q4.onnx` | CPU | Not faithful for this checkpoint: paraphrases instead of copying. Kept for reference. |
45
+
46
+ ## Results of the int8 export
47
+
48
+ Scored through transformers.js (onnxruntime-node, `dtype: "int8"`) on the two
49
+ lessons held out of training, two sections each, in all seven document layouts
50
+ the training data used:
51
+
52
+ | layout | parsed | passage words | spelling | prompts | answers |
53
+ | ----------------------------- | -----: | ------------: | -------: | ------: | ------: |
54
+ | Word export as raw text | 100% | 100% | 100% | 100% | 100% |
55
+ | numbered, bracketed answers | 100% | 100% | 100% | 100% | 100% |
56
+ | Q and A lines | 100% | 100% | 81% | 100% | 98% |
57
+ | bare capitals, no headings | 75% | 75% | 75% | 75% | 75% |
58
+ | bullets, square brackets | 100% | 100% | 100% | 100% | 100% |
59
+ | numbered, colon | 100% | 100% | 100% | 98% | 96% |
60
+ | working-out on its own line | 100% | 100% | 100% | 100% | 100% |
61
+
62
+ The one miss in the capitals layout is a single long section where the reply
63
+ hit the 1,500-token cap before closing its JSON; the other three sections in
64
+ that layout were perfect. The model's own question types were right 93 to 99
65
+ percent of the time here, better than on the sample scored in the training
66
+ notebook.
67
 
68
  ## Use
69
 
70
  ```javascript
71
  import { AutoModelForCausalLM, AutoTokenizer } from "@huggingface/transformers";
72
 
73
+ const repo = "playforgecoding/LFM2-1.2B-Extract-lesson-ONNX";
74
+ const tokenizer = await AutoTokenizer.from_pretrained(repo);
75
+ const model = await AutoModelForCausalLM.from_pretrained(repo, {
76
+ dtype: "q4f16",
77
+ device: "webgpu",
78
+ });
79
+
80
  const inputs = tokenizer.apply_chat_template(
81
  [
82
+ {
83
+ role: "system",
84
+ content:
85
+ "Return data as a JSON object with the following schema:\n" + schema,
86
+ },
87
  { role: "user", content: sectionText },
88
  ],
89
  { add_generation_prompt: true, return_dict: true },
90
  );
91
+ const output = await model.generate({
92
+ ...inputs,
93
+ max_new_tokens: 1500,
94
+ do_sample: false,
95
+ });
96
+ console.log(
97
+ tokenizer.batch_decode(output.slice(null, [inputs.input_ids.dims[1], null]), {
98
+ skip_special_tokens: true,
99
+ })[0],
100
+ );
101
  ```
102
 
103
  ## How it was converted
104
 
105
+ `python -m onnxruntime_genai.models.builder -i merged -p int4 -e webgpu` for
106
+ q4f16 and `-e cpu` for q4, then `relayout-onnx.py` from the Spelling Creator
107
+ repo, which renames the convolution caches to `past_conv.N`, makes the KV
108
+ cache's head dimension concrete, moves the chat template into
109
+ `tokenizer_config.json`, adds the `transformers.js_config` block, and puts the
110
+ graphs under `onnx/`. The route is written up at
111
+ [spellingcreator.org/docs/monorepo/document-import-experiment](https://spellingcreator.org/docs/monorepo/document-import-experiment).
112
 
113
  ## Licence
114
 
115
+ Derived from LFM2-1.2B-Extract and released under the same LFM Open License
116
+ v1.0 (see LICENSE).