Downloads · 30 days
4
19% of all-time downloads
minhpa/lab22-dpo-vn
lab22-dpo-vn is a text generation model from minhpa. Use it when you need the model to write or continue text. It is set up for peft. The card lists the license as apache-2.0.
LoRA adapter for unsloth/Qwen2.5-3B-bnb-4bit, trained with SFT → DPO for the VinUni AICB Track 3 Day 22 (DPO/ORPO Alignment) lab.
Downloads · 30 days
4
19% of all-time downloads
All-time downloads
21
Public
Repo size
131 MB
Likes
0
Public
Click a slice to open those files.
.safetensors120 MB · 88%
From the Hugging Face model README
LoRA adapter for unsloth/Qwen2.5-3B-bnb-4bit, trained with SFT → DPO for the
VinUni AICB Track 3 Day 22 (DPO/ORPO Alignment) lab.
This is a single self-contained adapter: DPO training (below) continued fine-tuning the SFT LoRA weights in place (warm start) rather than stacking a second adapter on top, so this checkpoint already includes both the SFT and the DPO effect. Load it directly on top of the base model — no separate SFT adapter is needed.
q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj| Stage | Dataset | Size |
|---|---|---|
| SFT | bkai-foundation-models/vi-alpaca | 1,000 samples, 1 epoch |
| DPO | argilla/ultrafeedback-binarized-preferences-cleaned | 5,000 preference pairs (train) + 50 (eval), 1 epoch |
| Metric | Value |
|---|---|
| Final training loss | 0.7696 |
| Chosen reward (log π/π_ref) | -0.682 |
| Rejected reward (log π/π_ref) | -0.831 |
| Reward gap (chosen − rejected) | +0.149 |
Both chosen and rejected reward stay below 0 throughout training (noisy, oscillating in the -0.6 to -1.0 range over ~620 steps) — rejected drops slightly more than chosen, giving a small positive but noisy gap rather than a clean, stable separation. Consistent with a short run (5k pairs, 1 epoch, lr=5e-7) rather than a fully converged DPO run.
| Result | Count |
|---|---|
| SFT+DPO wins | 4/8 |
| SFT-only wins | 2/8 |
| Tie | 2/8 |
Both models failed to refuse 2 out of 4 safety-probe prompts (tie = both unsafe) — DPO training on general helpfulness preference data did not by itself teach refusal behavior for those cases.
from unsloth import FastLanguageModel
from unsloth.chat_templates import get_chat_template
from peft import PeftModel
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="unsloth/Qwen2.5-3B-bnb-4bit",
max_seq_length=512,
dtype=None,
load_in_4bit=True,
)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
tokenizer = get_chat_template(tokenizer, chat_template="qwen2.5")
model = PeftModel.from_pretrained(model, "minhpa/lab22-dpo-vn")
FastLanguageModel.for_inference(model)
messages = [{"role": "user", "content": "Giải thích ngắn gọn thuật toán quicksort."}]
inputs = tokenizer.apply_chat_template(messages, return_tensors="pt", add_generation_prompt=True).to("cuda")
out = model.generate(input_ids=inputs, max_new_tokens=200)
print(tokenizer.decode(out[0][inputs.shape[1]:], skip_special_tokens=True))
Note: the base repo ships without a chat_template — get_chat_template(tokenizer, chat_template="qwen2.5") must be called before apply_chat_template().
This is a small-scale educational lab artifact (3B model, 1 epoch, 5k preference pairs) — not a production-safety-tuned model. As shown above, it does not reliably refuse unsafe requests (2/4 safety probes failed for both SFT-only and SFT+DPO). Do not deploy as-is for any safety-sensitive use.
Lab: VinUni AICB Track 3, Day 22 — DPO/ORPO Alignment. Stack: Unsloth, TRL, PEFT, bitsandbytes.