Instructions to use inspirebek/qwen3-4b-uzbek-v2-lora with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use inspirebek/qwen3-4b-uzbek-v2-lora with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("unsloth/Qwen3-4B") model = PeftModel.from_pretrained(base_model, "inspirebek/qwen3-4b-uzbek-v2-lora") - Notebooks
- Google Colab
- Kaggle
qwen3-4b-uzbek-v2-lora
raw lora adapter (~2 gb) for Qwen/Qwen3-4B. apply on top of the base model via peft.
usage
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
base = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-4B", dtype=torch.bfloat16, device_map="auto")
tok = AutoTokenizer.from_pretrained("inspirebek/qwen3-4b-uzbek-v2-lora")
model = PeftModel.from_pretrained(base, "inspirebek/qwen3-4b-uzbek-v2-lora")
model = model.merge_and_unload() # optional
for most users the pre-merged inspirebek/qwen3-4b-uzbek-v2 is simpler.
training
a two-stage lora fine-tune of Qwen/Qwen3-4B. the hard parts weren't the training loop — they were figuring out why v1 failed, then engineering around a 16-hour compute timeout that couldn't fit the full run.
the v1 lesson: why plain lora collapsed to random
v1 scored 26.92% on mmlu-uz, statistically indistinguishable from 25% random baseline. the adapter was training and loss was descending, but the model learned nothing useful in uzbek. root cause: lora only touched the attention and mlp projections. for a base model with english-dominant pretraining, learning a new language requires re-mapping the vocabulary itself — which lives in embed_tokens (input embeddings) and lm_head (output projection). freezing both means the model can't reshape its token distribution over uzbek morphology, only nudge how it attends within the english-shaped geometry it already has.
v2 adds embed_tokens and lm_head to target_modules. this expands the lora to ~2 gb (vs ~200 mb in v1) but finally lets the model actually learn uzbek. result: mmlu-uz jumped to 40.50% (+13.58 pp over random).
recipe
lora configuration (unsloth + peft):
r=64,alpha=128— alpha = 2·r (more aggressive updates than the conservative alpha=r default)use_rslora=True— alpha scales byalpha/sqrt(r)instead ofalpha/r; without this the per-parameter update magnitude at r=64 is too small and training stagnates- target modules:
q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj, embed_tokens, lm_head use_gradient_checkpointing="unsloth"to fit the expanded adapter on a single l4
dual learning rate (via UnslothTrainer):
- base lr for projection layers,
embedding_learning_rateat 1/10th forembed_tokens+lm_head - embeddings are the highest-leverage layer — a full-lr update can catastrophically drift the model's token geometry in the first few hundred steps
stage a — continued pretraining on native uzbek text (3 datasets, ~2m rows):
lr=5e-5,embedding_lr=5e-6, 1 epoch,packing=False- the goal is to reshape the token distribution so the model fluently predicts uzbek sequences, not to learn task behavior
stage b — supervised fine-tune on chat-formatted uzbek instructions (6 datasets, ~4.3m rows):
- loaded from the stage a adapter (continues training, not a fresh start)
lr=1e-4,embedding_lr=1e-5, 1 epochtrain_on_responses_only=True: the loss is masked on the user side of the qwen3 chat template so gradient only flows through assistant responses; prevents the model from memorizing prompt patterns and gives +1–2% accuracy empirically
stable batching:
per_device_train_batch_size=1,gradient_accumulation_steps=16— effective batch 16- at r=64 with embedding lora, batch 2 oom's on 24gb. the accumulation trick keeps gradient signal while staying inside the vram budget
optimization: adamw_8bit (bitsandbytes) + cosine schedule + 3% warmup, weight decay 0.01, seed 3407.
infra: surviving a 16-hour timeout on serverless gpu
modal functions have a 16-hour hard cap. stage b doesn't fit in 16 hours on a single l4, and a mid-epoch restart on a fresh container would lose everything (the /ckpts/ volume persists, but the container that owns the training state doesn't).
the fix: a TrainerCallback that pushes each checkpoint to a private hugging face repo (inspirebek/qwen3-4b-uzbek-ckpts) on every save_steps fire. when the container timed out at step 7258 / 8242 (88%), the next run loaded checkpoint-7000 from the hf backup and resumed — on a different modal account, after the first account's $30 credit ran out. account switches are invisible to huggingface; the backup was the portable state.
total stage b runtime: ~10 h first leg + ~3.2 h resume leg = ~13.2 h on a single l4.
evaluation
- mmlu-uz (murodbek/MMLU-uz, zero-shot, logit-based multiple choice): 40.50% overall
- social sciences 45.43%, other 45.07%, business 42.42%, stem 41.67%, medical 39.67%, humanities 35.60%
- uzlib (tahrirchi/uzlib, uzbek linguistic benchmark, sampled generation t=1.0 p=0.95): 33.42% overall
- correct_word 34.98%, fill_in 30.77%, meaning 26.69%, meaning_in_context 25.00%
- 8.17% of responses didn't parse cleanly as
A/B/C/D— a fraction of the score loss is format drift, not knowledge
datasets
stage a — fluency (continued pretraining):
yakhyo/uz-wiki· MITtahrirchi/uz-books-v2· MITtahrirchi/uz-crawl· Apache-2.0
stage b — instruct (sft):
saillab/alpaca_uzbek_taco· CC-BY-NC-4.0behbudiy/alpaca-cleaned-uz· CC-BY-4.0UAzimov/uzbek-instruct-llm· Apache-2.0CohereLabs/aya_collection_language_split· Apache-2.0med-alex/qa_mt_ru_to_uzn· unspecifiedmed-alex/qa_mt_tr_to_uzn· unspecified
⚠️ licensing note:
saillab/alpaca_uzbek_tacois cc-by-nc-4.0, which restricts commercial use of derivative models. downstream users who need a fully permissive license should retrain without that subset.
sibling formats
- Downloads last month
- 3