Qwen3 8B [V2] is a LoRA adapter fine-tuned on top of
Qwen/Qwen3-8B to improve Italian cultural alignment using exclusively
thinking-format (synthetic chain-of-thought) training data. It was trained on a thinking-converted version of the
Mult-IT dataset and evaluated on the
ITALIC benchmark. V2 is the second version in a series of experiments exploring how supervised fine-tuning data format affects both cultural performance and the chain-of-thought reasoning capabilities of Qwen3's hybrid-reasoning architecture.
Author: Maruf Bepary, King's College London
Research report: Alignment in Large Language Models
This confirms that the training data format directly determines which inference mode benefits from SFT. The reasoning-mode collapse observed in V1 was caused entirely by the non-thinking data format, not by the LoRA fine-tuning process itself.
A notable additional result: V2 Thinking (77.87%) surpasses the baseline Thinking (74.49%) and approaches Qwen3 14B Thinking (78.78%) despite being an 8B model — demonstrating that targeted SFT compensates meaningfully for the size gap.
Benchmark: ITALIC (NAACL 2025) — Italian Culture-Aware Natural Language Benchmark
Format: Zero-shot, multiple-choice (12 categories, 10,000 questions)
System prompt: "Sei un assistente utile."
1from transformers import AutoTokenizer, AutoModelForCausalLM
2from peft import PeftModel
3import torch
4import re
5
6base_model_id = "Qwen/Qwen3-8B"
7adapter_id = "maruf-bepary/qwen3-8b-italian-v2-thinking"
8
9# Load tokeniser and base model
10tokenizer = AutoTokenizer.from_pretrained(base_model_id)
11model = AutoModelForCausalLM.from_pretrained(
12 base_model_id,
13 torch_dtype=torch.bfloat16,
14 device_map="auto",
15)
16
17# Load LoRA adapter
18model = PeftModel.from_pretrained(model, adapter_id)
19model.eval()
20
21# Example: Italian multiple-choice question
22messages = [
23 {"role": "system", "content": "Sei un assistente utile."},
24 {
25 "role": "user",
26 "content": (
27 "Qual è la capitale d'Italia?\n"
28 "A) Milano\nB) Roma\nC) Napoli\nD) Torino\n\n"
29 "Rispondi con la lettera della risposta corretta."
30 ),
31 },
32]
33
34# Apply chat template — enable thinking mode (recommended for V2)
35text = tokenizer.apply_chat_template(
36 messages,
37 tokenize=False,
38 add_generation_prompt=True,
39 enable_thinking=True, # <-- primary mode for V2
40)
41
42inputs = tokenizer(text, return_tensors="pt").to(model.device)
43
44with torch.no_grad():
45 outputs = model.generate(
46 **inputs,
47 max_new_tokens=512,
48 do_sample=False,
49 temperature=None,
50 top_p=None,
51 )
52
53full_response = tokenizer.decode(
54 outputs[0][inputs["input_ids"].shape[-1]:],
55 skip_special_tokens=True,
56)
57
58# Strip the <think>...</think> block to extract the final answer
59final_answer = re.sub(r"<think>.*?</think>", "", full_response, flags=re.DOTALL).strip()
60print(final_answer)
61# Expected output: "B"
1# No Thinking mode — near-baseline performance
2text = tokenizer.apply_chat_template(
3 messages,
4 tokenize=False,
5 add_generation_prompt=True,
6 enable_thinking=False, # near-baseline; thinking mode is preferred for V2
7)