Frontiers commited on
Commit
6e1dcae
·
verified ·
1 Parent(s): efc52c9

add research-reports/raport_qwen38_27b.md

Browse files
Files changed (1) hide show
  1. research-reports/raport_qwen38_27b.md +223 -0
research-reports/raport_qwen38_27b.md ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Raport: QLoRA fine-tune pe Qwen3.8-27B (arhitectură hibridă, `model_type=qwen3_5`) pe Kaggle T4×2
2
+
3
+ Verificat live pe HuggingFace (curl), GitHub API și docs Unsloth — 9 oct 2026.
4
+ Hardware țintă: Kaggle T4×2 (2×16 GB = 32 GB, Turing sm_75, fp16 only, fără FlashAttention-2).
5
+
6
+ ---
7
+
8
+ ## 0. TL;DR / verdict
9
+
10
+ **DA, se poate** — și e chiar **calea oficială** recomandată de Unsloth. Există un notebook Kaggle
11
+ oficial pentru exact acest scenariu (Qwen3.8-27B, 2×T4). Dar există 3 capcane mari care, dacă nu
12
+ sunt respectate, dau crash:
13
+
14
+ 1. **NU pune `device_map="balanced"`** — folosește default-ul Unsloth `"sequential"`.
15
+ 2. **NU seta `fp16=True`, NU forța `dtype=torch.float16`** — Gated DeltaNet dă gradient NaN în fp16 pur; Unsloth ține arhitectura pe un path de autocast **float32**.
16
+ 3. **`max_seq_length` realist = 1024** pe 2×T4 (nu 2048). Seq 2048 este posibil doar cu reduceri agresive (fără MLP LoRA / offload embedding) și este la limită.
17
+
18
+ ---
19
+
20
+ ## 1. TRANSFORMERS SUPPORT pentru `qwen3_5`
21
+
22
+ **Confirmat din `config.json` real** (https://huggingface.co/Qwen/Qwen3.8-27B/raw/main/config.json):
23
+
24
+ - `architecture`: **`Qwen3_5ForConditionalGeneration`**
25
+ - `model_type` top-level: **`qwen3_5`**; `text_config.model_type`: **`qwen3_5_text`**; `vision_config.model_type`: `qwen3_5`
26
+ - `transformers_version` în config: `5.8.0.dev0`
27
+ - **NU are `auto_map`** în config → **`trust_remote_code` NU este necesar**. Este arhitectură nativă în `transformers`.
28
+
29
+ **Versiune minimă transformers (verificat live pe raw.githubusercontent.com, tag= vX.Y.Z → src/transformers/models/qwen3_5/__init__.py):**
30
+
31
+ | tag | HTTP |
32
+ |---|---|
33
+ | v5.1.0 | 404 (nu există) |
34
+ | **v5.2.0** | **200 (prima versiune cu `qwen3_5`)** |
35
+ | v5.5.x / v5.6.0 / v5.8.0 / v5.9.0 / v5.10.0+ | 200 |
36
+
37
+ - **Minim real: `transformers >= 5.2.0`.** În practică folosește **>= 5.15.1** (ce fixează notebook-ul Unsloth). Ultima pe PyPI acum: **5.19.0**. Unsloth recomandă „latest v5".
38
+
39
+ **Fișiere native în transformers** (`src/transformers/models/qwen3_5/`): `configuration_qwen3_5.py`, `modeling_qwen3_5.py` (~1967 linii), `modular_qwen3_5.py`, `tokenization_qwen3_5.py`.
40
+
41
+ **Clase expuse:** `Qwen3_5ForConditionalGeneration`, `Qwen3_5ForCausalLM`, `Qwen3_5Model`, `Qwen3_5TextModel`, `Qwen3_5ForSequenceClassification`, `Qwen3_5ForTokenClassification`, **`Qwen3_5GatedDeltaNet`**, `Qwen3_5Attention`, `Qwen3_5MLP`, `Qwen3_5DecoderLayer`, `Qwen3_5VisionModel`.
42
+
43
+ ---
44
+
45
+ ## 2. QLoRA pe 27B — VRAM real
46
+
47
+ **Parametri reali** (din HF safetensors metadata): **27.781.427.952 (27.78 B)**, toți în BF16 (~55.6 GB pe disc).
48
+
49
+ - **NF4 pur ≈ 14.2 GB** doar pentru weights.
50
+ - **Real, măsurat de Unsloth (notebook Kaggle): 18.80 GiB weights resident** (include embedding input untied + `lm_head` în precizie mai mare; vocab 248320 × 5120 ⇒ `lm_head` ≈ 1.27 B params ≈ 2.37 GiB dacă rămâne necuantizat).
51
+ - **Peak reserved: 23.71 GiB** (numărul care dă OOM; include fragmentare).
52
+ - Splash: **7.08 GiB pe cuda:0** și **11.36 GiB pe cuda:1** (a doua e cea „strâmtă", pentru că ține `lm_head`)
53
+ - Activații + grad + optimizer: doar **1.23 GiB la peak** (datorită LoRA r=8 + grad ckpt).
54
+
55
+ **Concluzie fit:**
56
+ - **O singură T4 (16 GB) NU încape** (notebook-ul are `assert torch.cuda.device_count() >= 2`).
57
+ - **2×T4 (32 GB) încape**, cu sharding secvențial.
58
+ - **`device_map`**: NU pasa `"balanced"` (lăsa `lm_head` fără loc și bitsandbytes refuză entry CPU). Lasa default-ul Unsloth `"sequential"`.
59
+
60
+ **Optimizer / checkpointing:**
61
+ - `optim = "adamw_8bit"` (paged_adamw_8bit echivalent) — **OK**, e exact ce folosește notebook-ul.
62
+ - `use_gradient_checkpointing = "unsloth"` — recomandat („30% less VRAM, fits 2× larger batch").
63
+ - `per_device_train_batch_size = 1`, `gradient_accumulation_steps = 4` — **deliberat**. Vocabularul 248320 face logits cea mai mare alocare din pas.
64
+
65
+ **Batch / seq:**
66
+ - Notebook-ul folosește **`max_seq_length = 1024`** (comentariu explicit: „Qwen3.8 goes to 262144, but **1024 is what two T4s train on**").
67
+ - **`seq=2048`**: fezabil dar la limită pe cuda:1 (care la 1024 are 11.36/16 GiB). Activațiile ar cam dubla ~1.23 GiB → ~2.5 GiB, deci ar putea intra, dar recomandarea lor e să scazi seq sau să oprești `finetune_mlp_modules`.
68
+ - **bs=1 e obligatoriu** practic; batch mai mare = OOM garantat.
69
+
70
+ **LoRA bf16 (non-QLoRA):** nu încape — Unsloth: Qwen3.8 **LoRA > 36 GB**, Qwen3.5-27B bf16 LoRA **56 GB**.
71
+
72
+ **Atenție QLoRA:** Unsloth avertizează că pe Qwen3.5 „**QLoRA 4-bit nu e recomandat**" din cauza diferențelor mari de cuantizare (mai ales MoE), dar **pentru dense 27B QLoRA e OK** (în ghidul Qwen3.5: „dense 27B is fine"). Pentru Qwen3.8 ei promovează explicit QLoRA „works with 24GB".
73
+
74
+ ---
75
+
76
+ ## 3. LINEAR ATTENTION — implementare și kernel-uri pe T4
77
+
78
+ **Arhitectură** (din config + README Qwen): layout **16 × (3 × (Gated DeltaNet → FFN) → 1 × (Gated Attention → FFN))** ⇒ **48 layere linear_attention + 16 full_attention** (`full_attention_interval=4`). Este **Gated DeltaNet stil Qwen3-Next**.
79
+
80
+ **Implementare native în transformers** (`modeling_qwen3_5.py`):
81
+ - Clasă **`Qwen3_5GatedDeltaNet`** decorată `@use_kernel_forward_from_hub("Qwen3_5GatedDeltaNet")` + `@use_kernelized_func([...])`.
82
+ - Funcții pure-PyTorch cu **fallback garantat**:
83
+ - `torch_chunk_gated_delta_rule` (decorator `@use_kernel_func_from_hub_with_fallback("chunk_gated_delta_rule", "fla")`)
84
+ - `torch_recurrent_gated_delta_rule` (`@use_kernel_func_from_hub_with_fallback("fused_recurrent_gated_delta_rule", "fla")`)
85
+ - `causal_conv1d_fn` / `causal_conv1d_update` (`@use_kernel_func_from_hub_with_fallback("causal_conv1d_fn", "causal_conv1d")`)
86
+ - Proiecții Gated DeltaNet: `in_proj_qkv`, `in_proj_z`, `in_proj_b`, `in_proj_a`, `out_proj`, plus `conv1d` (nn.Conv1d, grupat) și `norm` (RMSNormGated).
87
+
88
+ **Ce rulează concret pe T4 (sm_75):**
89
+ - **`causal-conv1d` compilează pentru sm_75** — confirmat direct în `setup.py`: `cc_flag.append("arch=compute_75,code=sm_75")`. ✅
90
+ - **FlashAttention-2 NU** suportă sm_75 (necesită sm_80+) → pe T4 full-attention-ul folosește **SDPA** (memory-efficient attention din PyTorch). `_supports_flash_attn = True` dar nu e disponibil pe Turing.
91
+ - **`flash-linear-attention` (fla)**: Triton. Cu decoratorul `..._with_fallback` **există fallback PyTorch**, deci **modelul rulează chiar și fără fla/causal-conv1d instalate** — doar mai lent și mai consumator de memorie. Nu e hard-dependency.
92
+ - Unsloth folosește **kernel-uri Triton Mamba/linear-attention proprii**; docs: „compiling those kernels can take longer than normal, **especially on T4 GPUs**".
93
+
94
+ **🚨 CAPCANĂ CRITICĂ fp16 (din notebook-ul Kaggle oficial):**
95
+ > „Do not pass `dtype = torch.float16`, and do not set `fp16 = True`. **The gated delta net produces NaN gradients in pure float16**, so Unsloth keeps this architecture on a **float32 autocast path** and picks the loading dtype itself. The heavy matmuls still use the T4's float16 tensor cores either way."
96
+ - Deci: lași `fp16`/`bf16` necompletate, lași Unsloth să decidă.
97
+ - Bug conex (GPT fără bf16, ex. T4): cu `use_gradient_checkpointing="unsloth"` un buffer intern era bf16 → mismatch `BFloat16 != Half`; fix în **unsloth-zoo#1316** (issue Unsloth #7506, „Crash on T4 Kaggle environment qwen 3.5 bf16 training").
98
+
99
+ ---
100
+
101
+ ## 4. TARGET MODULES LoRA pe `qwen3_5`
102
+
103
+ **Verificat prin calcul** = exact **496 module / 58.36 M params (0.21%)**, cifrele din notebook. Setul complet de proiecții `nn.Linear`:
104
+
105
+ - **Full attention (16 layere)** — 4/layer → 64 module:
106
+ `q_proj`, `k_proj`, `v_proj`, `o_proj`
107
+ (atenție: `q_proj` scoate **2×** pentru `attn_output_gate=True` → out = 24×256×2)
108
+ - **Linear attention / Gated DeltaNet (48 layere)** — 5/layer → 240 module:
109
+ `in_proj_qkv`, `in_proj_z`, `in_proj_b`, `in_proj_a`, `out_proj`
110
+ - **MLP (64 layere)** — 3/layer → 192 module:
111
+ `gate_proj`, `up_proj`, `down_proj`
112
+
113
+ Total = 64 + 240 + 192 = **496**. ✅
114
+
115
+ **NU se targetează:**
116
+ - `q_norm` / `k_norm` → sunt **RMSNorm** (weight 1D), nu Linear.
117
+ - `conv1d` → este **`nn.Conv1d`**, nu `nn.Linear` (PEFT nu îl prinde nici cu `"all-linear"`).
118
+ - `norm` (RMSNormGated), layernorm-uri, `A_log`/`dt_bias` (parametri de recurență).
119
+
120
+ **Config LoRA din notebook:** `r=8`, `lora_alpha=8`, `lora_dropout=0`, `bias="none"`.
121
+ - r=8 → 58.36 M trainabili (0.21%). r=16 → ~117 M (~0.42%).
122
+ - HuggingFace PEFT: `target_modules="all-linear"` funcționează (prinde toate nn.Linear de mai sus). Unsloth `get_peft_model(finetune_language_layers=True, finetune_attention_modules=True, finetune_mlp_modules=True, finetune_vision_layers=False)` face asta automat (496 module = fix acest set).
123
+
124
+ ---
125
+
126
+ ## 5. Alternative dacă 27B QLoRA nu încape / nu merge
127
+
128
+ 1. **2×T4 cu `device_map="sequential"`** — calea oficială, DAR: trebuie exclus `"balanced"`, batch 1, seq ≤1024. Este deja „alternative"-ul real.
129
+ 2. **A100 80GB** — Unsloth are notebook oficial [Qwen3.5-27B A100(80GB)]; pe 80GB merge bf16 LoRA complet (56 GB VRAM).
130
+ 3. **CPU/embedding offload prin Unsloth**: opțiunea `offload_embedding=True` la `FastModel.from_pretrained` „keeps the large, untied input embedding in RAM" → reduce VRAM rezident (utilă dacă ești la limită). Unsloth o dezactivează automat pe platforme neacceptate.
131
+ 4. **Accelerate CPU offload (`device_map="auto"` + `offload_folder`)**: fezabil dar foarte lent (PCIe) și `lm_head` (2.37 GiB) e problematic la bitsandbytes — exact motivul pentru care notebook-ul interzice `"balanced"`.
132
+ 5. **Reduce consumul**: scazi `max_seq_length`, oprești `finetune_mlp_modules` (192 module din 496), `gradient_accumulation_steps` mai mare în loc de batch mai mare.
133
+ 6. **Cloud**: un singur A100/H100 e cel mai simplu; sau L40S/RTX 4090 24 GB (dar 24 GB e fix pentru QLoRA — fără al doilea card nu ai headroom; Unsloth zice QLoRA pe 24 GB totuși funcționează).
134
+ 7. **Full/LoRA bf16**: exclus pe T4 (56 GB).
135
+
136
+ ---
137
+
138
+ ## 6. Rețete reale (repo / HF / docs)
139
+
140
+ **Unsloth — rețeta oficială (cea mai relevantă, există notebook Kaggle T4×2):**
141
+ - Notebook Conversational Kaggle (Qwen3.8-27B): `github.com/unslothai/notebooks/blob/main/nb/Kaggle-Qwen3.8_(27B)-Conversational.ipynb`
142
+ - Docs: `https://unsloth.ai/docs/models/qwen3.8/train` (guide fine-tune) și `https://unsloth.ai/docs/models/qwen3.8`
143
+ - „For free Qwen3.8-27B fine-tuning… we provide multiple Kaggle notebooks that offer **30 hours of free GPU usage with 2× Tesla T4 GPUs**."
144
+ - „QLoRA works with 24GB and LoRA needs >36GB."
145
+ - „Unsloth utilizes **Flash Linear Attention kernels**… first run can take longer while the Gated DeltaNet kernels compile."
146
+
147
+ **Pachete/versiuni fixate în notebook (reale, din cell de instalare):**
148
+ ```
149
+ uv pip install bitsandbytes xformers unsloth
150
+ uv pip install triton "huggingface_hub>=0.34.0" "datasets==4.3.0"
151
+ uv pip install --no-deps --upgrade "torchao>=0.16.0"
152
+ uv pip install transformers==5.15.1
153
+ uv pip install --no-deps trl==0.22.2
154
+ ```
155
+ Versiuni curente pe PyPI: bitsandbytes 0.50.2, peft 0.21.2, unsloth 2026.10.3, trl 1.15.0 (notebook pinuiește 0.22.2 — atenție la incompat), accelerate 1.15.0, flash-attn 2.8.3.post1, causal-conv1d 1.7.0, flash-linear-attention 0.5.2, transformers 5.19.0.
156
+
157
+ **Config LoRA + trainer (exact din notebook):** vezi §4; `optim="adamw_8bit"`, `lr=2e-4`, `per_device_train_batch_size=1`, `gradient_accumulation_steps=4`.
158
+
159
+ **Repo-uri HF reale:**
160
+ - `Qwen/Qwen3.8-27B` (base, 27.78 B BF16, 18 shard-uri)
161
+ - `unsloth/Qwen3.8-27B-unsloth-bnb-4bit` (build 4-bit pentru QLoRA)
162
+ - `unsloth/Qwen3.8-27B` / `-GGUF` / `-NVFP4` / `-FP8`
163
+ - `Qwen/Qwen3.8-27B-FP8`, `nvidia/Qwen3.8-27B-NVFP4`, `mlx-community/Qwen3.8-27B-4bit`
164
+ - Fine-tune-uri comunitare: nerk yor SFT-RLOO-MTP, DavidAU (GGUF), etc.
165
+
166
+ **Unsloth suportă Qwen3.8?** DA — oficial, cu `FastModel`, `get_peft_model`, SFT + RL (GRPO), vision fine-tuning, și notebook Kaggle T4×2 dedicat.
167
+
168
+ ---
169
+
170
+ ## 7. Rețetă minimă recomandată pentru Kaggle T4×2 (extras din notebook oficial)
171
+
172
+ ```python
173
+ import torch
174
+ assert torch.cuda.device_count() >= 2 # T4 x2 obligatoriu
175
+
176
+ from unsloth import FastModel
177
+ max_seq_length = 1024 # 2048 = la limită pe T4x2
178
+
179
+ model, tokenizer = FastModel.from_pretrained(
180
+ model_name = "unsloth/Qwen3.8-27B-unsloth-bnb-4bit", # sau "unsloth/Qwen3.8-27B"
181
+ max_seq_length = max_seq_length,
182
+ load_in_4bit = True,
183
+ full_finetuning = False,
184
+ # NU pasa device_map="balanced" -> default "sequential" e ok
185
+ )
186
+
187
+ model = FastModel.get_peft_model(
188
+ model,
189
+ finetune_vision_layers = False,
190
+ finetune_language_layers = True,
191
+ finetune_attention_modules = True, # atinge și linear_attn (Gated DeltaNet)
192
+ finetune_mlp_modules = True,
193
+ r = 8, lora_alpha = 8, lora_dropout = 0, bias = "none",
194
+ use_gradient_checkpointing = "unsloth",
195
+ random_state = 3407,
196
+ )
197
+
198
+ from trl import SFTTrainer, SFTConfig
199
+ trainer = SFTTrainer(model=model, tokenizer=tokenizer, train_dataset=dataset,
200
+ args=SFTConfig(
201
+ dataset_text_field="text", max_length=max_seq_length,
202
+ per_device_train_batch_size=1, gradient_accumulation_steps=4,
203
+ warmup_steps=5, max_steps=30, learning_rate=2e-4,
204
+ optim="adamw_8bit", weight_decay=0.001, lr_scheduler_type="linear",
205
+ # NU seta fp16=True / bf16=True <-- cheie pe T4
206
+ seed=3407, output_dir="outputs", report_to="none",
207
+ ))
208
+ trainer = train_on_responses_only(trainer) # antrenează doar pe răspunsuri
209
+ trainer.train()
210
+ ```
211
+
212
+ **Bugete reale (măsurate de Unsloth, cap pe 2 carduri):** weights 18.80 GiB, activații+grad+optim 1.23 GiB, peak reserved **23.71 GiB** (7.08 + 11.36 GiB). Notă: memoria a fost măsurată pe un card mare limitat la capacitatea a două T4-uri — **timpul per step nu a fost măsurat pe T4**, deci training-ul va fi net mai lent decât pe Ampere.
213
+
214
+ ---
215
+
216
+ ## Sinteza celor 6 întrebări
217
+
218
+ 1. **Transformers**: `qwen3_5` nativ din **transformers ≥ 5.2.0** (recomandat ≥ 5.15.1). Clasa `Qwen3_5ForConditionalGeneration`. **Fără `trust_remote_code`** (nu are `auto_map`).
219
+ 2. **VRAM**: NF4 ~14.2 GB, real rezident 18.80 GiB, peak reserved **23.71 GiB**. O T4 NU ajunge; **2×T4 încap la bs=1, seq=1024** (seq=2048 la limită). `paged_adamw_8bit`/adamw_8bit + grad ckpt OK.
220
+ 3. **Linear attention**: **Gated DeltaNet stil Qwen3-Next**, cu fallback PyTorch (rulează și fără kernels). `causal-conv1d` are build sm_75; FA2 nu suportă Turing (se folosește SDPA). **Capcană: NaN în fp16 → NU seta fp16**; Unsloth ține autocast float32.
221
+ 4. **Target modules**: 496 module = `q/k/v/o_proj` + `in_proj_qkv/z/b/a` + `out_proj` + `gate/up/down_proj`. Nu `q_norm/k_norm` (RMSNorm) și nu `conv1d`.
222
+ 5. **Alternative**: 2×T4 secvențial (calea oficială), 1×A100 80GB, `offload_embedding=True`, CPU offload (lent), reducere seq/MLP. LoRA bf16 exclus pe T4 (56 GB).
223
+ 6. **Rețete**: Unsloth are notebook Kaggle T4×2 dedicat + docs. Suport Qwen3.8 oficial în Unsloth (FastModel, SFT, RL, vision).