merge study: --merge-lora artifacts — Q4 merge erases the adapter (measured), Q8_0/F16 preserve it; standalone merged-Q8_0 + provenance
Browse files- .gitattributes +1 -0
- README.md +44 -11
- evals/merged-F16.json +1 -0
- evals/merged-Q4_K_M.json +1 -0
- evals/merged-Q8_0.json +1 -0
- merged/merged-F16.gguf.merge.json +1 -0
- merged/merged-Q4_K_M.gguf.merge.json +1 -0
- merged/merged-Q8_0.gguf +3 -0
- merged/merged-Q8_0.gguf.merge.json +1 -0
.gitattributes
CHANGED
|
@@ -37,3 +37,4 @@ Qwen3-4B-ToolUse-LoRA.gguf filter=lfs diff=lfs merge=lfs -text
|
|
| 37 |
study/adapter-trained-through-Q4_K_M.gguf filter=lfs diff=lfs merge=lfs -text
|
| 38 |
study/adapter-trained-through-Q8_0.gguf filter=lfs diff=lfs merge=lfs -text
|
| 39 |
study/adapter-trained-through-bf16.gguf filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 37 |
study/adapter-trained-through-Q4_K_M.gguf filter=lfs diff=lfs merge=lfs -text
|
| 38 |
study/adapter-trained-through-Q8_0.gguf filter=lfs diff=lfs merge=lfs -text
|
| 39 |
study/adapter-trained-through-bf16.gguf filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
merged/merged-Q8_0.gguf filter=lfs diff=lfs merge=lfs -text
|
README.md
CHANGED
|
@@ -100,19 +100,48 @@ difference costs nothing: every adapter scores 1.000, and the bf16- and
|
|
| 100 |
Q8-trained adapters drop onto the Q4_K_M serving base at 1.000 too. All
|
| 101 |
three study adapters and their provenance records are in `study/`.
|
| 102 |
|
| 103 |
-
##
|
| 104 |
|
| 105 |
-
`
|
| 106 |
-
|
|
|
|
|
|
|
|
|
|
| 107 |
|
| 108 |
-
|
|
| 109 |
-
|---|---|
|
| 110 |
-
|
|
| 111 |
-
|
|
| 112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
|
| 114 |
-
|
| 115 |
-
commands against the shas above to re-measure it yourself.
|
| 116 |
|
| 117 |
## Honest limits
|
| 118 |
|
|
@@ -131,5 +160,9 @@ commands against the shas above to re-measure it yourself.
|
|
| 131 |
|
| 132 |
- `Qwen3-4B-ToolUse-LoRA.gguf` — the adapter (+ `.train.json` provenance)
|
| 133 |
- `data/` — the deterministic dataset (train + held-out eval)
|
| 134 |
-
- `evals/` — every eval JSON quoted above, unedited
|
|
|
|
| 135 |
- `study/` — the three precision-study adapters, provenance, divergence
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
Q8-trained adapters drop onto the Q4_K_M serving base at 1.000 too. All
|
| 101 |
three study adapters and their provenance records are in `study/`.
|
| 102 |
|
| 103 |
+
## The merge study (`merged/`) — or: why this repo ships an adapter
|
| 104 |
|
| 105 |
+
Runner's `--merge-lora` folds the adapter into the base weights
|
| 106 |
+
(`W' = W + (alpha/r)·B·A`, deterministic: same inputs → byte-identical
|
| 107 |
+
merged file) so the result runs in **any** GGUF runtime. We merged this
|
| 108 |
+
adapter into three output precisions of the same Q4_K_M base and re-ran
|
| 109 |
+
the held-out eval on each standalone file:
|
| 110 |
|
| 111 |
+
| merged into | right tool | exact call | verdict |
|
| 112 |
+
|---|---|---|---|
|
| 113 |
+
| Q4_K_M (base's own type) | 0.724 | 0.690 | **adapter erased — scores exactly the base** |
|
| 114 |
+
| Q8_0 | **1.000** | **1.000** | behavior fully preserved |
|
| 115 |
+
| F16 | **1.000** | **1.000** | behavior fully preserved |
|
| 116 |
+
|
| 117 |
+
The 4-bit merge is not slightly worse — it reproduces the base's numbers
|
| 118 |
+
to the prompt. Byte-level comparison shows why: after requantizing to
|
| 119 |
+
Q4_K_M, only **1.45% of weight bytes differ from the base** — the LoRA
|
| 120 |
+
delta is small relative to the 4-bit grid step, so quantization rounds it
|
| 121 |
+
back to the original codes almost everywhere. The visible symptom (via
|
| 122 |
+
stock llama.cpp b10581, raw completion): the Q8_0 and F16 merges answer
|
| 123 |
+
with JSON only, exactly as trained; the Q4_K_M merge answers, then drifts
|
| 124 |
+
into conversational prose — the base's behavior.
|
| 125 |
+
|
| 126 |
+
**Deployment guidance, measured:** to serve 4-bit with this adaptation,
|
| 127 |
+
serve `base + --lora` (exact, and how the 1.000 row above is produced).
|
| 128 |
+
To ship a standalone merged file, merge into Q8_0 or wider and *measure
|
| 129 |
+
it* — this repo's `merged/merged-Q8_0.gguf` is that artifact, verified
|
| 130 |
+
1.000 on the eval and runnable in stock llama.cpp. Merging into a 4-bit
|
| 131 |
+
base is where fine-tunes silently disappear; if you do it anywhere, eval
|
| 132 |
+
the merged file, not the adapter.
|
| 133 |
+
|
| 134 |
+
The Q4_K_M and F16 merges are not uploaded (one is behaviorally the base,
|
| 135 |
+
the other is 8 GB); their provenance records with sha256s are in
|
| 136 |
+
`merged/`, and because the merge is deterministic, one command reproduces
|
| 137 |
+
either file byte-for-byte:
|
| 138 |
+
|
| 139 |
+
```sh
|
| 140 |
+
runner -m Qwen_Qwen3-4B-Q4_K_M.gguf --lora Qwen3-4B-ToolUse-LoRA.gguf \
|
| 141 |
+
--merge-lora merged-Q4_K_M.gguf # sha256 17443f0d55f5bb33…
|
| 142 |
+
```
|
| 143 |
|
| 144 |
+
(`--merge-lora` needs runner newer than v0.2.0 — main at `54fe720`+.)
|
|
|
|
| 145 |
|
| 146 |
## Honest limits
|
| 147 |
|
|
|
|
| 160 |
|
| 161 |
- `Qwen3-4B-ToolUse-LoRA.gguf` — the adapter (+ `.train.json` provenance)
|
| 162 |
- `data/` — the deterministic dataset (train + held-out eval)
|
| 163 |
+
- `evals/` — every eval JSON quoted above, unedited (incl. the three
|
| 164 |
+
merged-artifact evals)
|
| 165 |
- `study/` — the three precision-study adapters, provenance, divergence
|
| 166 |
+
- `merged/` — the standalone merged Q8_0 GGUF (runs in any GGUF runtime,
|
| 167 |
+
verified 1.000 on the eval and smoke-tested in llama.cpp b10581) +
|
| 168 |
+
`.merge.json` provenance for all three merge targets
|
evals/merged-F16.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"model": "merged-F16.gguf", "adapter": false, "n": 29, "json_parses": 1.0, "right_tool": 1.0, "schema_args": 1.0, "exact_call": 1.0}
|
evals/merged-Q4_K_M.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"model": "merged-Q4_K_M.gguf", "adapter": false, "n": 29, "json_parses": 1.0, "right_tool": 0.7241, "schema_args": 0.7241, "exact_call": 0.6897}
|
evals/merged-Q8_0.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"model": "merged-Q8_0.gguf", "adapter": false, "n": 29, "json_parses": 1.0, "right_tool": 1.0, "schema_args": 1.0, "exact_call": 1.0}
|
merged/merged-F16.gguf.merge.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"schema_version":"xyntetik.runner.merge.v1","runner":"0.2.0","base":{"path":"/home/lab/workspace/models/Qwen3-4B-tooluse/Qwen_Qwen3-4B-Q4_K_M.gguf","sha256":"fbe1d5edd4ce802ae3ae7c7e4ab7d09789d697fdac1fc7929f8df4ca3c41bae3"},"adapter":{"path":"/tmp/hf-repo/Qwen3-4B-ToolUse-LoRA.gguf","sha256":"ea38f80c33d381c9aa62c874920d2fa058dd307e7186e9b7c347d782f35b88e4"},"lora_scale":1,"target":"f16","merged":{"path":"/home/lab/workspace/models/Qwen3-4B-tooluse/merged-F16.gguf","sha256":"95f9a45d1859a6dcfdd34908066a3503ed18fd3c9104cafaf2e073823458f250"}}
|
merged/merged-Q4_K_M.gguf.merge.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"schema_version":"xyntetik.runner.merge.v1","runner":"0.2.0","base":{"path":"/home/lab/workspace/models/Qwen3-4B-tooluse/Qwen_Qwen3-4B-Q4_K_M.gguf","sha256":"fbe1d5edd4ce802ae3ae7c7e4ab7d09789d697fdac1fc7929f8df4ca3c41bae3"},"adapter":{"path":"/tmp/hf-repo/Qwen3-4B-ToolUse-LoRA.gguf","sha256":"ea38f80c33d381c9aa62c874920d2fa058dd307e7186e9b7c347d782f35b88e4"},"lora_scale":1,"target":"keep","merged":{"path":"/home/lab/workspace/models/Qwen3-4B-tooluse/merged-Q4_K_M.gguf","sha256":"17443f0d55f5bb33d1de4ae3529446d42c2d9f06f258d160b4d2a9176b9cc9f1"}}
|
merged/merged-Q8_0.gguf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b9d21e525d91b20a1fc3437cf34c7ecfa03afda722d960b95bcfd113f2b7ea02
|
| 3 |
+
size 4280405440
|
merged/merged-Q8_0.gguf.merge.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"schema_version":"xyntetik.runner.merge.v1","runner":"0.2.0","base":{"path":"/home/lab/workspace/models/Qwen3-4B-tooluse/Qwen_Qwen3-4B-Q4_K_M.gguf","sha256":"fbe1d5edd4ce802ae3ae7c7e4ab7d09789d697fdac1fc7929f8df4ca3c41bae3"},"adapter":{"path":"/tmp/hf-repo/Qwen3-4B-ToolUse-LoRA.gguf","sha256":"ea38f80c33d381c9aa62c874920d2fa058dd307e7186e9b7c347d782f35b88e4"},"lora_scale":1,"target":"q8_0","merged":{"path":"/home/lab/workspace/models/Qwen3-4B-tooluse/merged-Q8_0.gguf","sha256":"b9d21e525d91b20a1fc3437cf34c7ecfa03afda722d960b95bcfd113f2b7ea02"}}
|