Kanitakorn-Qwen3-8B-SFT-v3 (research-driven recipe)

A LoRA adapter on top of Qwen/Qwen3-8B, third iteration with research-driven recipe fixes.

Differences from v1

change v1 v3 why
Loss masking text-mode loss-on-all (TRL default) assistant_only_loss=True TRL's text-mode trains the model to reproduce user turns โ€” addresses MT-Bench regression
Input format text field messages field required for assistant-only loss
LoRA rank r=64, alpha=128 r=16, alpha=32, use_rslora=True Biderman 2024: lower rank preserves base chat fluency
Learning rate 1e-4 5e-5 lower for stability with smaller rank
Dataset 4,147 Kanitakorn (gap-weighted Thai benchmark) 14,215 records: 4,215 Kanitakorn + 4,000 WangchanThaiInstruct + 3,000 WildChat + 1,500 OASST + 1,500 No Robots added chat-balanced data per Tulu-3 mixture proportions
Training 2 epochs, ~1,652 steps 1 epoch, 1,500 max steps one pass over the larger corpus
Contamination check n/a iapp/openthaieval test-only confirmed, NO OTE+CoT data added avoids inflating our OTE scores

Results

WARNING โ€” incomplete evaluation. Full benchmark eval was interrupted to free GPU for Round 4 (which uses Unsloth acceleration). Only partial data:

benchmark v3 v1 (for ref) sample
AIME24 0.154 0.033 n=13 (partial, larger sample needed)
(all other benchmarks) TODO โ€” eval was killed at step 13 of 285 โ€” โ€”

Use with caution: the AIME24 partial number is encouraging (4.7x vs v1) but n=13 has very wide CI. Reproduce in your own pipeline before using v3 over v1 for any decision.

Training recipe

LoraConfig(
    r=16, lora_alpha=32, target_modules='all-linear',
    lora_dropout=0.05, bias='none', task_type='CAUSAL_LM',
    use_rslora=True,
)
SFTConfig(
    num_train_epochs=1, max_steps=1500,
    per_device_train_batch_size=2, gradient_accumulation_steps=8,
    learning_rate=5e-5, bf16=True,
    warmup_ratio=0.05, weight_decay=0.01,
    lr_scheduler_type='cosine',
    neftune_noise_alpha=5.0,
    assistant_only_loss=True,  # KEY DIFFERENCE
    gradient_checkpointing=True,
)

Usage

from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel

base = "Qwen/Qwen3-8B"
adapter = "Jnx03/kanitakorn-qwen3-8b-sft-v3"
tok = AutoTokenizer.from_pretrained(base, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(base, torch_dtype="bfloat16", device_map="auto")
model = PeftModel.from_pretrained(model, adapter).merge_and_unload()

Honest disclosure

v3 is an experimental iteration testing the assistant_only_loss + rsLoRA + chat-balanced corpus hypotheses from our research. We released the checkpoint for transparency, but did not finish evaluating it before pivoting to v4 (Unsloth-accelerated, larger corpus). v1 remains the recommended production model until v3/v4 are fully benchmarked.

See https://huggingface.co/datasets/Jnx03/kanitakorn-th-sft for the full development log.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for Jnx03/kanitakorn-qwen3-8b-sft-v3

Finetuned
Qwen/Qwen3-8B
Adapter
(1983)
this model

Dataset used to train Jnx03/kanitakorn-qwen3-8b-sft-v3