KBBridge commited on
Commit
486e3b6
·
verified ·
1 Parent(s): 66b774e

Model card

Browse files
Files changed (1) hide show
  1. README.md +263 -0
README.md ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ base_model: KBBridge/KBBridge-v3
4
+ base_model_relation: quantized
5
+ tags: [genexus, code-generation, qwen3, fp8, vllm]
6
+ language: [es, en]
7
+ pipeline_tag: text-generation
8
+ ---
9
+ # KBBridge-v3 (FP8)
10
+
11
+ A fine-tune of [`Qwen/Qwen3.8-27B`](https://huggingface.co/Qwen/Qwen3.8-27B) specialised in
12
+ **GeneXus** programming, in the native `.gxSource` export format.
13
+
14
+ Frontier models do not know this format. Without the GeneXus documentation injected into the
15
+ prompt they produce syntactically invalid output almost every time (parse rate 0.5–3.1%).
16
+ KBBridge writes it natively, runs on your own hardware, and never sends your Knowledge Base
17
+ code to an external API.
18
+
19
+ ---
20
+
21
+ ## ⚠️ Read this before your first prompt
22
+
23
+ Two settings, or the model will look broken. Both are measured, not stylistic.
24
+
25
+ ### 1. Turn reasoning OFF
26
+
27
+ ```bash
28
+ # vLLM: pass it per request
29
+ # "chat_template_kwargs": {"enable_thinking": false}
30
+ ```
31
+
32
+ The Qwen chat template enables a `<think>` block by default. If that block does not close
33
+ within your token budget, the answer comes back **empty or half-finished** — the client sees
34
+ "the model did not respond". Measured on this GGUF: with reasoning on, 300 tokens were not
35
+ enough to even begin the object; with it off, the same prompt returned a complete, valid
36
+ `Procedure`.
37
+
38
+ Our own gateway sets this by default for exactly this reason.
39
+
40
+ ### 2. Ask for the format explicitly
41
+
42
+ Write **"in `.gxSource` format"** in your prompt.
43
+
44
+ Measured on v3: the bare request *"a Procedure that adds two numbers"* returns generic **SQL**.
45
+ Naming the format returns the GeneXus object, consistently. If you use a harness with its own
46
+ system prompt, put the instruction there once.
47
+
48
+ ### 3. Give it enough room
49
+
50
+ `max_tokens` ≥ 4096. A `.gxSource` object consumes roughly **340 tokens per KB** of source, and
51
+ most tools default to 512–1024, which truncates the object mid-body.
52
+
53
+ ---
54
+
55
+ ## Results
56
+
57
+ 580 held-out items (191 codegen + 329 MCQ + 60 data-model) that no model saw during training.
58
+ Syntax validated with the official GeneXus ANTLR parser. Same protocol for every model:
59
+ temperature 0.1, reasoning off, concurrency 8.
60
+
61
+ ### v3 vs v2 — an honest comparison
62
+
63
+ **v3 is not a clean win over v2.** It gains domain knowledge and loses syntax accuracy:
64
+
65
+ | Metric | v2 | **v3** | |
66
+ |---|---|---|---|
67
+ | parseRate (valid syntax) | **89.0** | 84.8 | −4.2 |
68
+ | parmMatch (exact signature) | 78.6 | 78.6 | = |
69
+ | MCQ (GeneXus knowledge) | 76.0 | **79.0** | +3.0 |
70
+ | methodValidity | 90.0 | **91.1** | +1.1 |
71
+
72
+ **What these numbers do NOT establish.** v3 changed three things at once — the base model
73
+ (Qwen3.6 → 3.8), the corpus (4× larger, per-KB cap removed) and the teacher (v1 → v2). The
74
+ parseRate drop **cannot be attributed** to any one of them without a control arm that was never
75
+ run. Anyone reading this table as "the bigger corpus hurt syntax" is over-reading it.
76
+
77
+ Choose v3 if domain knowledge matters more to you; v2 still leads on raw syntax validity.
78
+
79
+ ### Generalisation to unseen Knowledge Bases
80
+
81
+ Three entire KBs were held out — different domains, never in the pipeline:
82
+
83
+ | | held-out from training KBs | 3 completely new KBs |
84
+ |---|---|---|
85
+ | v2 | 89.0 | 89.9 |
86
+ | **v3** | 84.8 | **87.4** |
87
+
88
+ v3's *relative* gap to unseen KBs is larger than v2's (+2.6 vs +0.9), i.e. it generalises
89
+ better in relative terms, even though two KBs make up 54.7% of its corpus.
90
+
91
+ ### Fairness note on the frontier comparison
92
+
93
+ In our benchmark the frontier models were run **with** ~21,600 tokens of GeneXus documentation
94
+ injected into every request; KBBridge was run **without** any. That is not a handicap we
95
+ imposed — injecting the same documentation into KBBridge makes it *worse* (76.4 → 73.3
96
+ parseRate), because the fine-tune already internalised that knowledge and the extra context
97
+ gets in the way. Still, the setups differ, and you should know that when reading any
98
+ head-to-head number.
99
+
100
+ ### About quantisation quality
101
+
102
+ The 4-bit GGUF build was measured against the bf16 master on the same 580 items, and
103
+ **excluding items where either run hit the token ceiling the two are indistinguishable**
104
+ (parseRate 93.0 vs 93.6 over 171 items). FP8 is a lighter quantisation than that, so the same
105
+ conclusion applies with room to spare — though we did not benchmark this FP8 build separately.
106
+
107
+ ---
108
+
109
+ ## Files
110
+
111
+ FP8 dynamic quantisation, **29 GB**, single shard. Built for vLLM on Hopper/Blackwell-class
112
+ GPUs. This is the build we run in production.
113
+
114
+ ```bash
115
+ vllm serve KBBridge/KBBridge-v3-FP8 --served-model-name kbbridge-v3 \
116
+ --max-model-len 262144 --kv-cache-dtype fp8 \
117
+ --reasoning-parser qwen3 --enable-auto-tool-choice --tool-call-parser qwen3_coder
118
+ ```
119
+
120
+ > ### ⚠️ This build has no MTP head
121
+ >
122
+ > It was quantised before the multi-token-prediction head was restored to the bf16 master, so
123
+ > its 1,680 tensors include the vision tower but **not** the 15 MTP tensors. Speculative
124
+ > decoding is therefore unavailable here.
125
+ >
126
+ > That costs real speed: on the GGUF build, enabling the MTP head took generation from 62 to
127
+ > **109 tok/s (+71%)**. If you need that, quantise your own FP8 from
128
+ > [`KBBridge/KBBridge-v3`](https://huggingface.co/KBBridge/KBBridge-v3), which does include it.
129
+ > We will replace this build when we re-quantise.
130
+
131
+ ## Intended use
132
+
133
+ Assisting GeneXus developers: generating objects (Procedures, Transactions, Data Providers,
134
+ SDTs, WebPanels), explaining existing code, completion, and documentation questions.
135
+
136
+ **Out of scope:** not a general-purpose model, not a replacement for validating in the GeneXus
137
+ IDE, and it does not know any particular Knowledge Base (see *Limitations*).
138
+
139
+ ---
140
+
141
+ ## Limitations
142
+
143
+ - **It does not know your KB.** It learned the style and syntax of the format, not the contents
144
+ of any specific base. Ask it about a transaction you did not paste in, and it will **invent
145
+ plausible attribute names and present them as fact**. Always give it the context and validate
146
+ the output in the IDE.
147
+ - **Runaway generation on very large objects.** For objects over ~10 KB the model can fall into
148
+ degenerate repetition — the same line hundreds of times without closing the object. Measured
149
+ on v2 at ~1.6% of benchmark items; **not re-measured on v3**. Raising `max_tokens` does not
150
+ fix it. Generate large objects section by section.
151
+ - **Spanish bias** in explanations, reflecting the corpus.
152
+ - **Specialised**: worse than the base model at general tasks.
153
+ - The limitations above other than the first were measured on **v2** and are carried over as
154
+ working assumptions, not verified properties of v3.
155
+
156
+ ### If you also use a hosted KBBridge endpoint
157
+
158
+ The raw GGUF and a gateway-fronted deployment **do not behave the same by default**. Our
159
+ gateway applies four corrections the plain model does not have: a `max_tokens` floor, reasoning
160
+ disabled, a `reasoning_content` fallback when `content` comes back empty, and
161
+ `repetition_penalty` 1.05 to suppress runaway. If you compare "what I tried on your server"
162
+ against "what I downloaded", the difference is those four settings, not the weights.
163
+
164
+ ---
165
+
166
+ ## Training
167
+
168
+ | | |
169
+ |---|---|
170
+ | Method | QLoRA 4-bit (bitsandbytes) + Liger kernel |
171
+ | LoRA | r=64, α=128, dropout=0.05, all projections |
172
+ | Context | 12,288 tokens |
173
+ | Effective batch | 16 (1 × 16 grad accum) |
174
+ | LR | 1.0e-4, cosine, 3% warmup |
175
+ | Epochs | 2 complete (14,108 steps) |
176
+ | Hardware | 1× RTX PRO 6000 Blackwell 96 GB |
177
+ | Duration | 7 days 4:41 |
178
+ | Framework | LLaMA-Factory, transformers 5.6.0 |
179
+
180
+ train_loss **0.2618** (v2: 0.3344) · eval_loss **0.3723** (v2: 0.4675), minimum at the **last**
181
+ step — no overfitting across 71 evaluations, which suggests there was room for more epochs.
182
+
183
+ Note that these losses are much better than v2's and yet parseRate went *down*: `eval_loss`
184
+ measures fit to the corpus, not GeneXus quality.
185
+
186
+ ### Data
187
+
188
+ 80,344 examples derived from GeneXus objects across 25 real Knowledge Bases (GX16/17/17U8/18/
189
+ Evo1, multi-domain) — 129% more than v2, with the per-KB cap removed. Sanitised, deduplicated
190
+ and split by deterministic hash. **The datasets are not published**: they contain customer
191
+ proprietary code.
192
+
193
+ ---
194
+
195
+ ## Training-data privacy
196
+
197
+ The model was trained on real customer Knowledge Bases, so we audited whether it can leak them.
198
+ This is the strongest result of the project.
199
+
200
+ ### Canaries: no memorisation threshold found
201
+
202
+ 12 synthetic objects containing unguessable 16-character secrets were inserted at four
203
+ frequencies, and verified to have reached `train.jsonl` at exactly those counts:
204
+
205
+ | repetitions | canaries | recovered by name | recovered with literal prefix |
206
+ |---|---|---|---|
207
+ | 1 | 3 | 0/3 | 0/3 |
208
+ | 10 | 3 | 0/3 | 0/3 |
209
+ | 100 | 3 | 0/3 | 0/3 |
210
+ | **1000** | 3 | **0/3** | **0/3** |
211
+
212
+ **Not even at a thousand identical repetitions.** A control rules out a broken probe: asked for
213
+ the canary, the model returns a structurally valid but **empty** object — no token, no secret.
214
+ And it does generate real bodies when the request has content, so the empty skeleton is not an
215
+ inability to generate.
216
+
217
+ ### Membership inference: marginal signal
218
+
219
+ | | |
220
+ |---|---|
221
+ | mean loss, seen examples | 3.4130 |
222
+ | mean loss, unseen | 3.7711 |
223
+ | mean length | 3,133 vs 3,117 chars — comparable, so the AUC is meaningful |
224
+ | **AUC** | **0.5539** |
225
+
226
+ 0.554 against 0.50 for indistinguishable. There is a statistical trace of having seen the data,
227
+ but the distributions overlap almost entirely.
228
+
229
+ **Conclusion: customer code is not recoverable from the weights.**
230
+
231
+ **Caveat, stated plainly:** absence of evidence is not proof of absence. These audits cover the
232
+ attacks we ran, not every attack that exists.
233
+
234
+ ---
235
+
236
+ ## Reproducibility
237
+
238
+ Full external reproduction is **not possible**, and it is worth saying so directly:
239
+
240
+ 1. The 25 Knowledge Bases are customer code and are not distributed.
241
+ 2. The `parseRate` scorer uses the KBEditor's ANTLR parser — proprietary, not distributable.
242
+ 3. The teacher that generated v3's data is KBBridge-v2, which is not published.
243
+
244
+ What a third party *can* verify: the raw benchmark outputs (one model response per item) and
245
+ the scoring over them.
246
+
247
+ ---
248
+
249
+ ## Citation
250
+
251
+ ```bibtex
252
+ @misc{kbbridge-v3,
253
+ title = {KBBridge-v3: a GeneXus code assistant fine-tuned from Qwen3.8-27B},
254
+ author = {Nardone, Angelo},
255
+ year = {2026},
256
+ url = {https://huggingface.co/KBBridge/KBBridge-v3-FP8}
257
+ }
258
+ ```
259
+
260
+ ## License
261
+
262
+ Apache 2.0, inherited from the base model `Qwen/Qwen3.8-27B`. This is a modified derivative
263
+ work; see `NOTICE`.