Files
qwen2.5-coder-3b-distilled-…/README.md

168 lines
5.8 KiB
Markdown
Raw Normal View History

---
language:
- en
license: apache-2.0
base_model: Qwen/Qwen2.5-Coder-3B-Instruct
tags:
- qwen2.5
- code
- knowledge-distillation
- gkd
- qlora
- python
- causal-lm
datasets:
- iamtarun/python_code_instructions_18k_alpaca
pipeline_tag: text-generation
---
# Qwen2.5-Coder-3B — GKD Distilled from 14B
A **merged** (LoRA-free) version of `Qwen2.5-Coder-3B-Instruct` whose weights have been updated via **Generalized Knowledge Distillation (GKD)** from `Qwen2.5-Coder-14B-Instruct` as the teacher.
The LoRA adapter was trained with TRL's `DistillationTrainer` on a single NVIDIA A100 80 GB (Google Colab) for ~5 hours, then merged back into the base weights so the model loads exactly like the original 3B — no adapter plumbing required.
---
## Evaluation — HumanEval pass@1
Greedy decoding, 164 Python programming tasks.
| Model | Passed | Total | pass@1 |
|---|---:|---:|---:|
| Base `Qwen2.5-Coder-3B-Instruct` | 133 | 164 | 81.1% |
| **This model (distilled, 300 steps)** | **137** | **164** | **83.5%** |
| Δ | +4 | — | **+2.44 pp** |
**Task-level breakdown:**
| Outcome | Count |
|---|---:|
| Both pass | 126 |
| Only distilled passes (gained) | 11 |
| Only base passes (lost) | 7 |
| Neither passes | 20 |
| **Net change** | **+4** |
**Gained tasks (11):** HumanEval/26, /64, /75, /89, /93, /95, /110, /123, /124, /125, /135 — reasoning-heavy string manipulation, cipher encoding, and date parsing problems.
**Lost tasks (7):** HumanEval/10, /46, /99, /103, /141, /154, /159 — precise numeric/sequence edge cases (bankers rounding, fib4 base cases, cyclic rotation).
> Note: HumanEval pass@1 with greedy decoding has ~±2pp noise. The +2.44pp delta is at the edge of statistical significance for a 300-step run; longer training is expected to widen the gap.
---
## Training Details
### Setup
| Component | Detail |
|---|---|
| **Teacher** | `Qwen/Qwen2.5-Coder-14B-Instruct` — frozen, loaded in 4-bit NF4 |
| **Student** | `Qwen/Qwen2.5-Coder-3B-Instruct` + LoRA (r=16, α=32) |
| **Distillation** | TRL `DistillationTrainer`, GKD with λ=0.25, β=0.5 |
| **Dataset** | `iamtarun/python_code_instructions_18k_alpaca` — 17,681 train / 931 eval |
| **Hardware** | Google Colab A100 80 GB |
| **Wall time** | ~5 hours |
### GKD Loss
```
L = λ · L_on_policy + (1−λ) · L_teacher_forced
where L = β · KL(student ∥ teacher) + (1−β) · KL(teacher ∥ student)
```
- **λ=0.25** — 25% on-policy (student-generated) sequences, 75% teacher-forced; keeps training stable at low step counts while reducing exposure bias.
- **β=0.5** — symmetric Jensen–Shannon divergence between teacher and student logits.
### Hyperparameters
| Hyperparameter | Value |
|---|---|
| LoRA rank (r) | 16 |
| LoRA alpha | 32 |
| LoRA dropout | 0.05 |
| Target modules | q/k/v/o_proj, gate/up/down_proj |
| Optimizer | paged_adamw_8bit |
| Learning rate | 1.5e-4 |
| LR schedule | Cosine with 30-step warmup |
| Max steps | 300 |
| Per-device batch size | 16 |
| Gradient accumulation | 2 (effective batch = 32) |
| Max sequence length | 1024 |
| Precision | bf16 |
| Quantization (both models) | 4-bit NF4, double quant, bf16 compute |
---
## Usage
This is a standard causal-LM checkpoint — load it exactly like the base model.
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
model_id = "Harsha901/qwen2.5-coder-3b-distilled-from-14b-merged"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype=torch.bfloat16,
device_map="auto",
)
messages = [
{"role": "user", "content": "Write a Python function that checks if a number is prime."}
]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
)
inputs = tokenizer([text], return_tensors="pt").to(model.device)
with torch.no_grad():
output = model.generate(
**inputs,
max_new_tokens=512,
do_sample=False,
)
print(tokenizer.decode(output[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))
```
### Memory requirements
| Precision | Approx. VRAM |
|---|---|
| bf16 (this checkpoint) | ~6.5 GB |
| 4-bit NF4 (bitsandbytes) | ~2.5 GB |
The model runs comfortably on a 24 GB consumer GPU (RTX 3090/4090) in full bf16 precision.
---
## Limitations and Future Work
- **Only 300 steps trained** — the model has seen ~9,600 examples (~0.54 epochs of the training set). Longer training (1,000–2,000 steps or 3 full epochs) is expected to improve further.
- **Regressions on arithmetic edge cases** — the 7 lost tasks suggest slight distribution shift away from precise numeric corner cases; increasing LoRA rank or adding targeted examples may help.
- **Training dataset is Python-only** — generalisation to other languages is untested.
- **Distillation dataset differs from eval benchmark** — HumanEval is held-out; the training set is `python_code_instructions_18k_alpaca`, which covers general Python instruction-following rather than competitive algorithmic problems.
Planned next steps:
1. Train for 1,000+ steps and track HumanEval every 50 steps.
2. Tune λ toward 0.5–0.75 for more on-policy exposure.
3. Benchmark inference latency and VRAM vs. the 14B teacher to quantify serving cost reduction.
---
## Related Resources
- **LoRA adapter (pre-merge):** [Harsha901/qwen2.5-coder-3b-distilled-from-14b](https://huggingface.co/Harsha901/qwen2.5-coder-3b-distilled-from-14b)
- **Base student model:** [Qwen/Qwen2.5-Coder-3B-Instruct](https://huggingface.co/Qwen/Qwen2.5-Coder-3B-Instruct)
- **Teacher model:** [Qwen/Qwen2.5-Coder-14B-Instruct](https://huggingface.co/Qwen/Qwen2.5-Coder-14B-Instruct)
- **Training dataset:** [iamtarun/python_code_instructions_18k_alpaca](https://huggingface.co/datasets/iamtarun/python_code_instructions_18k_alpaca)
- **TRL DistillationTrainer docs:** [huggingface.co/docs/trl](https://huggingface.co/docs/trl)