AmareshHebbar commited on
Commit
85ab5b4
Β·
verified Β·
1 Parent(s): 06bd032

docs: v3 model card - QDoRA rationale, richer inference samples, expanded tags

Browse files
Files changed (1) hide show
  1. README.md +181 -20
README.md CHANGED
@@ -8,15 +8,29 @@ tags:
8
  - code-generation
9
  - competitive-programming
10
  - qwen2.5-coder
11
- - qlora
12
- - unsloth
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  - algorithms
14
  language:
15
  - en
16
  library_name: peft
17
  pipeline_tag: text-generation
18
  datasets:
19
- - AmareshHebbar/leetcode-cpp-sft
20
  co2_eq_emissions:
21
  emissions: 0
22
  source: "estimate, not measured with a carbon-tracking tool"
@@ -31,18 +45,19 @@ model-index:
31
  <div align="center">
32
 
33
  # βš™οΈ LeetCode C++ Coder
34
- ### Qwen2.5-Coder-7B fine-tuned to solve LeetCode problems in C++
35
 
36
  [![Hugging Face](https://img.shields.io/badge/%F0%9F%A4%97%20Model-leetcode--cpp--qwen25--coder--7b-FFD21E)](https://huggingface.co/AmareshHebbar/leetcode-cpp-qwen25-coder-7b)
37
- [![Dataset](https://img.shields.io/badge/%F0%9F%A4%97%20Dataset-leetcode--cpp--sft-blue)](https://huggingface.co/datasets/AmareshHebbar/leetcode-cpp-sft)
38
  [![GGUF](https://img.shields.io/badge/GGUF-quantized-6f42c1)](https://huggingface.co/AmareshHebbar/leetcode-cpp-qwen25-coder-7b-GGUF)
39
  [![License](https://img.shields.io/badge/license-Apache%202.0-green)](https://www.apache.org/licenses/LICENSE-2.0)
40
  [![Base Model](https://img.shields.io/badge/base-Qwen2.5--Coder--7B-orange)](https://huggingface.co/unsloth/Qwen2.5-Coder-7B-Instruct)
 
41
  [![Ollama](https://img.shields.io/badge/-Ollama-000000?logo=ollama)](#ollama)
42
  [![vLLM](https://img.shields.io/badge/-vLLM-333333)](#vllm)
43
  [![TGI](https://img.shields.io/badge/-TGI-yellow)](#tgi)
44
 
45
- *Part of the [LeetCode Multi-Language Coder Suite](https://huggingface.co/collections/AmareshHebbar/leetcode-multi-language-coder-suite) β€” 4 language specialists, one base model*
46
 
47
  </div>
48
 
@@ -50,7 +65,7 @@ model-index:
50
 
51
  ## TL;DR
52
 
53
- Given a LeetCode-style problem statement and an algorithm tag, generates a working C++ solution.
54
 
55
  ```
56
  PROBLEM: Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
@@ -72,14 +87,44 @@ public:
72
  | | |
73
  |---|---|
74
  | **Base model** | [unsloth/Qwen2.5-Coder-7B-Instruct](https://huggingface.co/unsloth/Qwen2.5-Coder-7B-Instruct) |
75
- | **Method** | QLoRA, 4-bit NF4, rank 16 |
76
- | **Training data** | [leetcode-cpp-sft](https://huggingface.co/datasets/AmareshHebbar/leetcode-cpp-sft) |
77
- | **Weights here** | LoRA adapter only (~160MB) β€” load on top of the base model |
 
 
78
  | **GGUF build** | [leetcode-cpp-qwen25-coder-7b-GGUF](https://huggingface.co/AmareshHebbar/leetcode-cpp-qwen25-coder-7b-GGUF) β€” q4_k_m / q5_k_m / q8_0 |
79
  | **License** | Apache 2.0 |
80
 
81
  ---
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  ## Benchmarks (free, reproducible)
84
 
85
  Run `benchmark_suite.py` from the deployment kit to reproduce. All numbers are pass@1 unless noted.
@@ -88,11 +133,11 @@ Run `benchmark_suite.py` from the deployment kit to reproduce. All numbers are p
88
  |---|---|---|---|---|
89
  | [HumanEval-X](https://huggingface.co/datasets/THUDM/humaneval-x) | C++ | _run benchmark_suite.py_ | _run benchmark_suite.py_ | 164 problems, execution-verified |
90
  | [MultiPL-E](https://huggingface.co/datasets/nuprl/MultiPL-E) (HumanEval subset) | C++ | _run benchmark_suite.py_ | β€” | cross-check vs HumanEval-X |
91
- | Held-out LeetCode test split | C++ | _run benchmark_suite.py_ | β€” | from `leetcode-cpp-sft` test split, exact I/O match |
92
  | Tokens/sec (fp16, A40) | C++ | β€” | β€” | latency benchmark, see script |
93
  | Tokens/sec (GGUF q4_k_m, CPU) | C++ | β€” | β€” | latency benchmark, see script |
94
 
95
- > Numbers are intentionally left blank in this template β€” `benchmark_suite.py` fills a `results/leetcode-cpp-qwen25-coder-7b.json` file and this table should be regenerated from it (see deployment kit README).
96
 
97
  ---
98
 
@@ -142,6 +187,65 @@ outputs = model.generate(inputs, max_new_tokens=512, temperature=0.2, do_sample=
142
  print(tokenizer.decode(outputs[0][inputs.shape[1]:], skip_special_tokens=True))
143
  ```
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  ### Option B β€” Unsloth (2x faster load + inference)
146
 
147
  ```python
@@ -188,6 +292,18 @@ response = client.chat.completions.create(
188
  print(response.choices[0].message.content)
189
  ```
190
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  ### Option D β€” TGI (Text Generation Inference) {#tgi}
192
 
193
  ```bash
@@ -217,6 +333,17 @@ ollama create leetcode-cpp-qwen25-coder-7b -f Modelfile.cpp
217
  ollama run leetcode-cpp-qwen25-coder-7b "Problem: Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.\nAlgorithm: Hash Map"
218
  ```
219
 
 
 
 
 
 
 
 
 
 
 
 
220
  ### Option F β€” GGUF / llama.cpp direct (mobile/edge inference)
221
 
222
  ```bash
@@ -231,19 +358,43 @@ See `export_gguf.py` in the deployment kit for building q4_k_m / q5_k_m / q8_0 v
231
 
232
  ## Training details
233
 
234
- ### Data
235
 
236
- Trained on [leetcode-cpp-sft](https://huggingface.co/datasets/AmareshHebbar/leetcode-cpp-sft), built from the `doocs/leetcode` corpus: problem statement + input/output examples + algorithm tag β†’ verified C++ solution, one-to-many (problem β†’ multiple algorithm-tagged solutions).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
 
238
  ### Hyperparameters
239
 
240
  | Parameter | Value |
241
  |---|---|
 
242
  | LoRA rank (r) | 16 |
243
  | LoRA alpha | 32 |
244
  | LoRA dropout | 0 |
245
  | Target modules | q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj |
246
- | Quantization | 4-bit NF4 (QLoRA) |
247
  | Max sequence length | 2048 |
248
  | Optimizer | paged_adamw_8bit |
249
  | LR schedule | 2e-4, cosine |
@@ -256,7 +407,8 @@ Trained on [leetcode-cpp-sft](https://huggingface.co/datasets/AmareshHebbar/leet
256
  | **Cloud provider** | RunPod |
257
  | **CO2 estimate** | self-reported, not measured with a carbon tracker β€” treat as approximate |
258
 
259
- Fine-tuned with [Unsloth](https://github.com/unslothai/unsloth) + TRL's `SFTTrainer`.
 
260
 
261
  ---
262
 
@@ -268,19 +420,27 @@ Fine-tuned with [Unsloth](https://github.com/unslothai/unsloth) + TRL's `SFTTrai
268
 
269
  **Not exhaustive on complexity.** The model doesn't guarantee asymptotically optimal solutions β€” check the complexity claims yourself for performance-sensitive use.
270
 
 
 
271
  ---
272
 
273
  ## FAQ
274
 
275
  **Q: Can I merge the adapter into the base model?**
276
- Yes β€” `model.merge_and_unload()` after loading with PEFT, or Unsloth's `save_pretrained_merged()`.
277
 
278
- **Q: Why QLoRA instead of full fine-tuning?**
279
- Qwen2.5-Coder-7B already has strong code priors from pretraining; QLoRA specializes the output format and LeetCode-specific patterns without the cost of full fine-tuning.
 
 
 
280
 
281
  **Q: Which quantization should I use on mobile?**
282
  q4_k_m is the best size/quality tradeoff for phones; q5_k_m if you have RAM headroom; avoid q2/q3 for code generation β€” correctness drops sharply below 4-bit.
283
 
 
 
 
284
  ---
285
 
286
  ## Related models in this suite
@@ -300,8 +460,9 @@ q4_k_m is the best size/quality tradeoff for phones; q5_k_m if you have RAM head
300
 
301
  | Version | Notes |
302
  |---|---|
 
303
  | v2.0 | Added GGUF builds, Ollama/vLLM/TGI deployment, benchmark harness (HumanEval-X, MultiPL-E, held-out test split) |
304
- | v1.0 | Initial release β€” QLoRA fine-tune on leetcode-cpp-sft |
305
 
306
  ---
307
 
 
8
  - code-generation
9
  - competitive-programming
10
  - qwen2.5-coder
11
+ - dora
12
+ - qdora
13
+ - weight-decomposed-lora
14
+ - instruction-tuned
15
+ - sft
16
+ - algorithm-generation
17
+ - function-generation
18
+ - coding-assistant
19
+ - on-device
20
+ - gguf
21
+ - ollama
22
+ - vllm
23
+ - text-generation-inference
24
+ - doocs-leetcode
25
+ - synthetic-verification
26
+ - quantized
27
  - algorithms
28
  language:
29
  - en
30
  library_name: peft
31
  pipeline_tag: text-generation
32
  datasets:
33
+ - AmareshHebbar/leetcode-code-gen-datasets
34
  co2_eq_emissions:
35
  emissions: 0
36
  source: "estimate, not measured with a carbon-tracking tool"
 
45
  <div align="center">
46
 
47
  # βš™οΈ LeetCode C++ Coder
48
+ ### Qwen2.5-Coder-7B, QDoRA fine-tuned to solve LeetCode problems in C++
49
 
50
  [![Hugging Face](https://img.shields.io/badge/%F0%9F%A4%97%20Model-leetcode--cpp--qwen25--coder--7b-FFD21E)](https://huggingface.co/AmareshHebbar/leetcode-cpp-qwen25-coder-7b)
51
+ [![Dataset](https://img.shields.io/badge/%F0%9F%A4%97%20Dataset-leetcode--code--gen--datasets-blue)](https://huggingface.co/datasets/AmareshHebbar/leetcode-code-gen-datasets)
52
  [![GGUF](https://img.shields.io/badge/GGUF-quantized-6f42c1)](https://huggingface.co/AmareshHebbar/leetcode-cpp-qwen25-coder-7b-GGUF)
53
  [![License](https://img.shields.io/badge/license-Apache%202.0-green)](https://www.apache.org/licenses/LICENSE-2.0)
54
  [![Base Model](https://img.shields.io/badge/base-Qwen2.5--Coder--7B-orange)](https://huggingface.co/unsloth/Qwen2.5-Coder-7B-Instruct)
55
+ [![Method](https://img.shields.io/badge/method-QDoRA-critical)](#why-qdora)
56
  [![Ollama](https://img.shields.io/badge/-Ollama-000000?logo=ollama)](#ollama)
57
  [![vLLM](https://img.shields.io/badge/-vLLM-333333)](#vllm)
58
  [![TGI](https://img.shields.io/badge/-TGI-yellow)](#tgi)
59
 
60
+ *Part of the [LeetCode Multi-Language Coder Suite](https://huggingface.co/collections/AmareshHebbar/leetcode-multi-language-coder-suite) β€” 4 language specialists, one base model, one pipeline*
61
 
62
  </div>
63
 
 
65
 
66
  ## TL;DR
67
 
68
+ Given a LeetCode-style problem statement, its sample input/output, and an algorithm tag, generates a working C++ solution.
69
 
70
  ```
71
  PROBLEM: Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
 
87
  | | |
88
  |---|---|
89
  | **Base model** | [unsloth/Qwen2.5-Coder-7B-Instruct](https://huggingface.co/unsloth/Qwen2.5-Coder-7B-Instruct) |
90
+ | **Method** | QDoRA (quantized DoRA, not plain LoRA) |
91
+ | **Training data** | [leetcode-code-gen-datasets](https://huggingface.co/datasets/AmareshHebbar/leetcode-code-gen-datasets) config `cpp` |
92
+ | **Data provenance** | scraped from [doocs/leetcode](https://github.com/doocs/leetcode) (3,977 problems), execution-verified, no synthetic/LLM-generated solutions |
93
+ | **Data quality** | execution-checked against sample I/O (see dataset card for exact rate) |
94
+ | **Weights here** | QDoRA adapter only (~160MB) β€” load on top of the base model |
95
  | **GGUF build** | [leetcode-cpp-qwen25-coder-7b-GGUF](https://huggingface.co/AmareshHebbar/leetcode-cpp-qwen25-coder-7b-GGUF) β€” q4_k_m / q5_k_m / q8_0 |
96
  | **License** | Apache 2.0 |
97
 
98
  ---
99
 
100
+ ## Why QDoRA {#why-qdora}
101
+
102
+ DoRA splits each adapted weight into magnitude + direction and trains both, which follows full fine-tuning's behavior more closely than plain LoRA β€” important for code where small precision errors break correctness outright. 4-bit NF4 quantization of the frozen base keeps this affordable on a single 48GB GPU.
103
+
104
+ Concretely, versus the plain-QLoRA v1 release of this suite: DoRA adds a per-column
105
+ trainable magnitude vector on top of the usual low-rank direction update, so the
106
+ adapter can rescale a feature's importance instead of only rotating it. On a code
107
+ task where a single wrong operator or dropped edge case fails the whole solution,
108
+ that closer match to full fine-tuning's update pattern showed up as fewer
109
+ near-miss failures during our own qualitative review, at the same LoRA rank and
110
+ VRAM budget.
111
+
112
+ ```python
113
+ # training-side PEFT config (see build_language_datasets.py / trainer script for full pipeline)
114
+ from peft import LoraConfig
115
+
116
+ peft_config = LoraConfig(
117
+ r=16,
118
+ lora_alpha=32,
119
+ lora_dropout=0.0,
120
+ target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
121
+ use_dora=True, # <- this is what makes it QDoRA, not QLoRA
122
+ task_type="CAUSAL_LM",
123
+ )
124
+ ```
125
+
126
+ ---
127
+
128
  ## Benchmarks (free, reproducible)
129
 
130
  Run `benchmark_suite.py` from the deployment kit to reproduce. All numbers are pass@1 unless noted.
 
133
  |---|---|---|---|---|
134
  | [HumanEval-X](https://huggingface.co/datasets/THUDM/humaneval-x) | C++ | _run benchmark_suite.py_ | _run benchmark_suite.py_ | 164 problems, execution-verified |
135
  | [MultiPL-E](https://huggingface.co/datasets/nuprl/MultiPL-E) (HumanEval subset) | C++ | _run benchmark_suite.py_ | β€” | cross-check vs HumanEval-X |
136
+ | Held-out LeetCode test split | C++ | _run benchmark_suite.py_ | β€” | from `leetcode-code-gen-datasets` (`cpp`) test split, exact I/O match |
137
  | Tokens/sec (fp16, A40) | C++ | β€” | β€” | latency benchmark, see script |
138
  | Tokens/sec (GGUF q4_k_m, CPU) | C++ | β€” | β€” | latency benchmark, see script |
139
 
140
+ > Numbers are intentionally left blank in this template β€” `benchmark_suite.py` fills a `results/leetcode-cpp-qwen25-coder-7b.json` file and this table should be regenerated from it.
141
 
142
  ---
143
 
 
187
  print(tokenizer.decode(outputs[0][inputs.shape[1]:], skip_special_tokens=True))
188
  ```
189
 
190
+ ### Batch inference (many problems at once)
191
+
192
+ ```python
193
+ problems = [
194
+ "Problem: Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.\nAlgorithm: Hash Map",
195
+ "Problem: Given a string s, find the length of the longest substring without repeating characters.\nAlgorithm: two pointers / sliding window",
196
+ "Problem: Merge two sorted linked lists into one sorted list.\nAlgorithm: linked list, dummy head",
197
+ ]
198
+
199
+ prompts = [
200
+ tokenizer.apply_chat_template(
201
+ [{"role": "system", "content": "You are an expert C++ competitive programmer. Given a LeetCode-style problem statement and an algorithm tag, write a correct, efficient C++ solution."}, {"role": "user", "content": p}],
202
+ tokenize=False, add_generation_prompt=True,
203
+ )
204
+ for p in problems
205
+ ]
206
+ tokenizer.padding_side = "left"
207
+ batch = tokenizer(prompts, return_tensors="pt", padding=True).to(model.device)
208
+ outputs = model.generate(**batch, max_new_tokens=512, temperature=0.2, do_sample=True)
209
+ for i, o in enumerate(outputs):
210
+ print(f"--- solution {i} ---")
211
+ print(tokenizer.decode(o[batch['input_ids'].shape[1]:], skip_special_tokens=True))
212
+ ```
213
+
214
+ ### Streaming output (token-by-token)
215
+
216
+ ```python
217
+ from transformers import TextIteratorStreamer
218
+ from threading import Thread
219
+
220
+ streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
221
+ gen_kwargs = dict(input_ids=inputs, max_new_tokens=512, temperature=0.2, do_sample=True, streamer=streamer)
222
+ Thread(target=model.generate, kwargs=gen_kwargs).start()
223
+ for token in streamer:
224
+ print(token, end="", flush=True)
225
+ ```
226
+
227
+ ### Structured JSON output (code + complexity + explanation)
228
+
229
+ ```python
230
+ json_system_prompt = (
231
+ "You are an expert C++ competitive programmer. Given a LeetCode-style problem statement and an algorithm tag, write a correct, efficient C++ solution. "
232
+ 'Respond ONLY with JSON: {"code": "...", "time_complexity": "...", '
233
+ '"space_complexity": "...", "explanation": "..."}'
234
+ )
235
+ messages = [
236
+ {"role": "system", "content": json_system_prompt},
237
+ {"role": "user", "content": "Problem: Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.\nAlgorithm: Hash Map"},
238
+ ]
239
+ inputs = tokenizer.apply_chat_template(messages, return_tensors="pt", add_generation_prompt=True).to(model.device)
240
+ outputs = model.generate(inputs, max_new_tokens=512, temperature=0.1, do_sample=True)
241
+ raw = tokenizer.decode(outputs[0][inputs.shape[1]:], skip_special_tokens=True)
242
+
243
+ import json
244
+ result = json.loads(raw.strip().removeprefix("```json").removesuffix("```").strip())
245
+ print(result["code"])
246
+ print(result["time_complexity"], result["space_complexity"])
247
+ ```
248
+
249
  ### Option B β€” Unsloth (2x faster load + inference)
250
 
251
  ```python
 
292
  print(response.choices[0].message.content)
293
  ```
294
 
295
+ Streaming with vLLM's OpenAI-compatible endpoint:
296
+ ```python
297
+ stream = client.chat.completions.create(
298
+ model="leetcode-cpp-qwen25-coder-7b",
299
+ messages=[{"role": "user", "content": "Problem: Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.\nAlgorithm: Hash Map"}],
300
+ stream=True,
301
+ )
302
+ for chunk in stream:
303
+ if chunk.choices[0].delta.content:
304
+ print(chunk.choices[0].delta.content, end="", flush=True)
305
+ ```
306
+
307
  ### Option D β€” TGI (Text Generation Inference) {#tgi}
308
 
309
  ```bash
 
333
  ollama run leetcode-cpp-qwen25-coder-7b "Problem: Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.\nAlgorithm: Hash Map"
334
  ```
335
 
336
+ Python client against a local Ollama server:
337
+ ```python
338
+ import requests
339
+ r = requests.post("http://localhost:11434/api/generate", json={
340
+ "model": "leetcode-cpp-qwen25-coder-7b",
341
+ "prompt": "Problem: Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.\nAlgorithm: Hash Map",
342
+ "stream": False,
343
+ })
344
+ print(r.json()["response"])
345
+ ```
346
+
347
  ### Option F β€” GGUF / llama.cpp direct (mobile/edge inference)
348
 
349
  ```bash
 
358
 
359
  ## Training details
360
 
361
+ ### Why this base model
362
 
363
+ Qwen2.5-Coder-7B-Instruct was chosen over a general instruct model because its
364
+ pretraining already concentrates capacity on code β€” the QDoRA adapter only has to
365
+ specialize output format and LeetCode-specific conventions (function signatures,
366
+ in-place vs. new-array conventions, C++ idioms) rather than teach the model
367
+ to code from scratch. 7B was picked as the size that still fits comfortably in a
368
+ single-GPU QDoRA run while keeping enough headroom that the base model's code
369
+ reasoning survives adaptation.
370
+
371
+ ### Data pipeline
372
+
373
+ Source: [doocs/leetcode](https://github.com/doocs/leetcode), 3,977 problems with
374
+ English documentation. Each problem can have multiple solutions spanning different
375
+ algorithm tags (greedy, DP, two pointers, etc.) β€” the pipeline treats this as a
376
+ one-to-many problem-to-solution structure rather than picking a single "canonical" answer.
377
+
378
+ | Stage | What it does |
379
+ |---|---|
380
+ | `extract_doocs.py` | pulls problem statement + I/O examples + per-solution algorithm tag from doocs/leetcode |
381
+ | `verify.py` | executes each extracted solution against its sample I/O, drops anything that fails |
382
+ | `normalize.py` | standardizes formatting/whitespace and problem/solution schema across all 4 languages |
383
+ | `build_language_datasets.py` | splits into per-language configs and writes the final train/val/test SFT rows |
384
+
385
+ execution-checked against sample I/O (see dataset card for exact rate). Full extraction/verification/build code lives alongside the
386
+ [leetcode-code-gen-datasets](https://huggingface.co/datasets/AmareshHebbar/leetcode-code-gen-datasets) dataset card.
387
 
388
  ### Hyperparameters
389
 
390
  | Parameter | Value |
391
  |---|---|
392
+ | Method | QDoRA (`use_dora=True` in PEFT's `LoraConfig`) |
393
  | LoRA rank (r) | 16 |
394
  | LoRA alpha | 32 |
395
  | LoRA dropout | 0 |
396
  | Target modules | q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj |
397
+ | Base quantization | 4-bit NF4 |
398
  | Max sequence length | 2048 |
399
  | Optimizer | paged_adamw_8bit |
400
  | LR schedule | 2e-4, cosine |
 
407
  | **Cloud provider** | RunPod |
408
  | **CO2 estimate** | self-reported, not measured with a carbon tracker β€” treat as approximate |
409
 
410
+ Fine-tuned with [Unsloth](https://github.com/unslothai/unsloth) + TRL's `SFTTrainer`,
411
+ DoRA enabled via PEFT.
412
 
413
  ---
414
 
 
420
 
421
  **Not exhaustive on complexity.** The model doesn't guarantee asymptotically optimal solutions β€” check the complexity claims yourself for performance-sensitive use.
422
 
423
+ **Data recency.** Reflects the state of `doocs/leetcode` at the time of extraction β€” newer problems added to LeetCode after that snapshot won't be covered.
424
+
425
  ---
426
 
427
  ## FAQ
428
 
429
  **Q: Can I merge the adapter into the base model?**
430
+ Yes β€” `model.merge_and_unload()` after loading with PEFT, or Unsloth's `save_pretrained_merged()`. DoRA adapters merge the same way LoRA adapters do.
431
 
432
+ **Q: Why QDoRA instead of plain QLoRA?**
433
+ See [Why QDoRA](#why-qdora) above β€” short version: DoRA's magnitude/direction split tracks full fine-tuning more closely, which matters for code correctness.
434
+
435
+ **Q: Why QDoRA instead of full fine-tuning?**
436
+ Qwen2.5-Coder-7B already has strong code priors from pretraining; QDoRA gets most of full fine-tuning's adaptation quality at a fraction of the compute and without the overfitting risk of updating every parameter on a comparatively small SFT set.
437
 
438
  **Q: Which quantization should I use on mobile?**
439
  q4_k_m is the best size/quality tradeoff for phones; q5_k_m if you have RAM headroom; avoid q2/q3 for code generation β€” correctness drops sharply below 4-bit.
440
 
441
+ **Q: Does this model store or transmit my input?**
442
+ No β€” inference runs entirely on whatever infrastructure you deploy it to.
443
+
444
  ---
445
 
446
  ## Related models in this suite
 
460
 
461
  | Version | Notes |
462
  |---|---|
463
+ | v3.0 | Switched to QDoRA, added rationale + PEFT config, batch/streaming/JSON inference samples, expanded tags |
464
  | v2.0 | Added GGUF builds, Ollama/vLLM/TGI deployment, benchmark harness (HumanEval-X, MultiPL-E, held-out test split) |
465
+ | v1.0 | Initial release β€” QLoRA fine-tune |
466
 
467
  ---
468