--- base_model: Qwen/Qwen3-4B-Instruct-2507 library_name: peft pipeline_tag: text-classification license: apache-2.0 language: - vi tags: - lora - unsloth - peft - hallucination-detection - vietnamese - ViHallu metrics: - accuracy - f1 --- # ViHallu — Qwen3-4B-Instruct-2507 + LoRA (Hallucination Detection) Fine-tune **LoRA (16-bit, generative)** của `Qwen/Qwen3-4B-Instruct-2507` để phát hiện hallucination trong câu trả lời tiếng Việt của LLM, trên bộ dữ liệu **ViHallu**. Mô hình nhận (context, prompt, response) và sinh ra đúng một nhãn: - **NO (0)** — trả lời đúng, nhất quán với ngữ cảnh. - **INTRINSIC (1)** — trả lời mâu thuẫn/bóp méo thông tin trong ngữ cảnh. - **EXTRINSIC (2)** — trả lời bổ sung thông tin không có trong ngữ cảnh. > DS319 - Lab 6 · Lương Đắc Nguyên (23521041). ## Kết quả (test = 2.000 mẫu) | Accuracy | Precision (macro) | Recall (macro) | Macro-F1 | Sai format | |---|---|---|---|---| | **0.9110** | 0.9111 | 0.9111 | **0.9108** | 0 / 2000 | ### Confusion matrix ![confusion matrix](confusion_matrix.png) | Thực tế \ Dự đoán | no | intrinsic | extrinsic | Recall | |---|---|---|---|---| | **no** | 616 | 41 | 33 | 89.3% | | **intrinsic** | 8 | 627 | 37 | 93.3% | | **extrinsic** | 33 | 26 | 579 | 90.8% | ## Tham số huấn luyện | Tham số | Giá trị | |---|---| | Base model | `unsloth/Qwen3-4B-Instruct-2507` | | Phương pháp | Unsloth LoRA (16-bit, generative) | | LoRA r / alpha | 16 / 16 | | Epochs | 3 | | Learning rate | 2e-4 | | Batch / grad-accum | 4 / 4 (effective 16) | | Optimizer / scheduler | adamw_8bit / cosine | | max_seq_length | 4096 | | Train / Val / Test | 7.000 / 1.000 / 2.000 | | Train time | ~39 phút (A100-80GB) | (Xem thêm `params.json`, `metrics.json` trong repo.) ## Cách dùng ```python from transformers import AutoModelForCausalLM, AutoTokenizer from peft import PeftModel base = "Qwen/Qwen3-4B-Instruct-2507" tok = AutoTokenizer.from_pretrained(base) model = AutoModelForCausalLM.from_pretrained(base, device_map="cuda", dtype="bfloat16") model = PeftModel.from_pretrained(model, "Laplaces-Red-Devils/vihallu-qwen3-4b-lora") SYSTEM = ("Bạn là hệ thống phát hiện hallucination trong câu trả lời tiếng Việt của mô hình " "ngôn ngữ lớn. Dựa vào Ngữ cảnh, hãy phân loại Trả lời vào ĐÚNG MỘT nhãn:\n" "- NO: Trả lời đúng và nhất quán với thông tin trong Ngữ cảnh.\n" "- INTRINSIC: Trả lời mâu thuẫn hoặc bóp méo thông tin có trong Ngữ cảnh.\n" "- EXTRINSIC: Trả lời bổ sung thông tin KHÔNG xuất hiện trong Ngữ cảnh.\n" "Chỉ trả về DUY NHẤT một nhãn: NO, INTRINSIC, hoặc EXTRINSIC.") def classify(context, prompt, response): user = f"Ngữ cảnh: {context}\n\nCâu hỏi: {prompt}\n\nTrả lời: {response}\n\nNhãn:" msgs = [{"role": "system", "content": SYSTEM}, {"role": "user", "content": user}] text = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True) enc = tok(text, return_tensors="pt").to(model.device) out = model.generate(**enc, max_new_tokens=8, do_sample=False) return tok.decode(out[0, enc["input_ids"].shape[1]:], skip_special_tokens=True).strip() ```