Fix kernel OpenCL Mesa/rusticl per llama.cpp #1
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Questo file è un prompt auto-contenuto da dare a Claude Code direttamente sul
Windows DevKit 2023 (Snapdragon 8cx Gen 3 + GPU Adreno 690, Mesa/rusticl
custom già installata). Non presuppone che chi lo esegue abbia accesso alla
conversazione originale: tutto il contesto necessario è qui sotto.
Obiettivo finale: produrre un file
FIX.mdcon l'elenco esatto e verificatodelle modifiche da riportare in
llamacpp-opencl.Containerfile, così da poterintegrare il fix nel container senza dover ripetere il lavoro di scoperta.
Prompt da dare a Claude Code
Riferimento: stato attuale del Containerfile (per chi applicherà FIX.md)
llamacpp-opencl.Containerfilecontiene già, in ordine:FD6*come famiglia Adreno (necessaria sempre).cl_khr_subgroup_ballotcome prova di supportosubgroup, dato che Mesa non espone mai la stringa legacy
cl_khr_subgroups(necessaria sempre).-D cl_qcom_reqd_sub_group_sizenelle opzioni dicompilazione kernel (necessaria se si riattivano kernel che usano
REQD_SUBGROUP_SIZE_64/ADRENO_GPU).vload_half()per i 14 file*flat*.clcon puntatori halfscalari (copertura parziale, superata da questo lavoro).
-DGGML_OPENCL_USE_ADRENO_KERNELS=OFF(da rivalutare in base a FIX.md).Il pacchetto Mesa custom (
.debincontainers/llamacpp/deb/, tracciato viaGit LFS) è generato da
build-mesa.shnella stessa cartella e NON deve esseretoccato per questo lavoro - il problema è tutto lato llama.cpp/kernel OpenCL,
non lato driver.
FIX.md — llama.cpp OpenCL su Adreno 690 / Mesa rusticl (Windows DevKit 2023)
Risultato del lavoro di debug fatto direttamente sul DevKit reale (Snapdragon
8cx Gen 3, Adreno 690, Mesa/rusticl custom con fix subgroup Freedreno a6xx,
commit 185c89084ab7). Testato su
llama.cpp@049326a00(2026-07-09 e2026-07-10).
🟢 SECONDO AGGIORNAMENTO (2026-07-10): bug reale trovato e fixato — modelli
densi "normali" con
n_embd/dimensioni interne > 1024 falliscono sempreUn secondo giro di debug (partito da un crash reale riscontrato dall'utente
nel container con
Qwen3.6-27B-MTP-GGUF:Q2_K_XL) ha portato alla scopertadi un bug concreto e ben isolato, distinto da tutto quanto scritto sotto:
in 9 punti di
ggml-opencl.cpp, il calcolo dellocal_work_sizeper undispatch dei kernel confrontava
nth/cols/ecc. solo controCL_KERNEL_WORK_GROUP_SIZE(il limite di prodotto totale del work-group,2048 su questo device) ma mai contro
CL_DEVICE_MAX_WORK_ITEM_SIZES[0](il limite per-dimensione, 1024 su questo device — verificato via
clinfo: "Max work item sizes: 1024x1024x64", "Max work group size: 2048").Questi due limiti sono indipendenti nello standard OpenCL e vanno rispettati
entrambi; su device dove il limite per-dimensione è più stretto del limite
di prodotto (come questo), il codice esistente calcolava local_work_size
fino a 1536+ per modelli con
n_embd(o dimensioni analoghe) sopra 1024,violando il limite per-dimensione con
CL_INVALID_WORK_ITEM_SIZE(-55).Sintomo: qualunque modello con
n_embd(o la dimensione rilevante perquel kernel) superiore a 1024 falliva SEMPRE al caricamento, anche modelli
completamente "normali" senza MoE/SSM/altro — es. Qwen2.5-1.5B-Instruct
(
n_embd=1536), fallito in modo riproducibile sukernel_rms_norm_mulconlws=[1536,1,1]. Spiega perché nella sessione precedente solo il modellominuscolo Qwen2.5-0.5B (
n_embd<1024) risultava funzionante: non era unaquestione di "modelli piccoli vs grandi" in generale, ma di questa soglia
precisa.
Fix: aggiunto un campo
backend_ctx->max_work_item_size0(popolato unavolta all'init del device via
clGetDeviceInfo(..., CL_DEVICE_MAX_WORK_ITEM_SIZES, ...))e usato per clampare
max_workgroup_sizeconMIN(...)in tutti i 9 puntidi dispatch interessati:
kernel_rms_norm_mul,kernel_norm_mul_add,kernel_l2_norm_f32,kernel_get_rows_*,kernel_set_rows/ggml_cl_set,ggml_cl_add_id,kernel_argsort_f32_i32(nel supports_op),kernel_group_norm_mul_add,kernel_cumsum_blk. Altri 3 punti che usano lo stesso helper(
get_kernel_workgroup_size) sono stati verificati come già sicuri (limitanoesplicitamente a 64/256 indipendentemente dal device, quindi non toccano mai
il limite di 1024) e lasciati invariati.
Verificato funzionante (boot pulito, testato due volte separatamente):
Qwen2.5-0.5BeQwen2.5-1.5B-Instructcaricano ed eseguono correttamentesulla GPU dopo il fix (il secondo falliva sempre prima). Diff completo nel
file
opencl-mesa-rusticl.patchaggiornato accanto a questo file.⚠️ Questo fix è indipendente e complementare ai problemi ancora aperti
descritti sotto (MoE, SSM/MTP) — risolve una classe di crash diversa e più
generale (colpisce anche modelli densi "normali" abbastanza grandi), ma
NON risolve i problemi MoE/SSM descritti più sotto, che restano aperti.
🔴 AGGIORNAMENTO CRITICO (2026-07-10): i modelli MoE mandano in hang la GPU
Dopo aver scritto la prima versione di questo file (sezioni sotto, ancora
valide per i modelli densi), ho testato dei modelli MoE reali
(
granite-3.0-1b-a400m, 84MB di soli pesi offloadati, eQwen3.6-35B-A3B-UD-IQ4_NL, 18GB) e in ENTRAMBI i casi il processollama-servercrasha conCL_OUT_OF_RESOURCES(-5) sulla primissimascrittura OpenCL della sessione (anche un tensore F32 di poche KB tipo
output_norm.weight), indipendentemente da-ngl,--ctx-size,--fit,presenza del componente vision, o dimensione del modello.
Non è un limite di risorse software: ho verificato nel sorgente Mesa
(
src/gallium/frontends/rusticl/core/queue.rs) cheCL_OUT_OF_RESOURCESinquesto punto corrisponde esattamente a
pipe.device_reset_status() != PIPE_NO_RESET— cioè rusticl sta segnalandoche la GPU ha subito un vero reset hardware. Confermato anche via
dmesg(accesso root):19 hang consecutivi registrati durante questa sessione, uno per ogni processo
llama-serverlanciato con un modello MoE. Un devcoredump completo delcrash (
/sys/class/devcoredump/) è stato salvato in.crash_dumps/devcd6_moe_crash_*.datanel checkout locale usato per questolavoro (non incluso qui, contiene lo stream di comandi GPU codificato
ascii85 — servirebbe
crashdecdi Mesa, non buildato per mancanza di tempo,per decodificarlo fino al comando esatto che ha causato il fault).
Più grave: la recovery del driver (
hangcheck recover!) NON restituiscesempre un stato pulito. Dopo alcuni hang causati da modelli MoE, ANCHE il
modello denso Qwen2.5-0.5B (che aveva funzionato perfettamente in precedenza
nella stessa sessione) ha iniziato a fallire allo stesso modo — la GPU resta
degradata anche per carichi di lavoro diversi da quello che ha causato il
primo hang. Questo probabilmente spiega anche i riavvii completi del
sistema (non solo del processo) osservati nella prima parte di questa
sessione, prima che i 3 fix qui sotto fossero applicati: se la recovery
del driver a volte fallisce del tutto invece di limitarsi a un hangcheck
recover, il risultato può essere un crash dell'intero kernel/sistema.
Root cause esatta non confermata (richiederebbe
crashdecper decodificareil command stream GPU), ma l'ipotesi più probabile: con
GGML_OPENCL_USE_ADRENO_KERNELS=OFF, i tensori MoE ("*_exps.weight",dimensione 3D con l'asse esperti) passano dal path di conversione SOA_Q
generico (non quello Adreno-specifico
_trans4_ns, escluso dal flag) —questo path potrebbe non gestire correttamente la dimensione "esperti"
nell'indicizzazione del kernel di conversione, causando un accesso GPU fuori
dai limiti che il driver Mesa/Freedreno non degrada in modo pulito.
Raccomandazione pratica:
attualmente degradata da questa sessione di debug.
modelli densi (testati: Qwen2.5-0.5B Q4_K_M) sono confermati sicuri e
funzionanti. Il container aggiornato con le patch sotto va bene per
modelli densi; per MoE serve indagine ulteriore (idealmente con
crashdecper identificare il kernel esatto, o testandoADRENO_KERNELS=ONnonostante i suoi problemi noti di compilazione suikernel
_ns, per vedere se il path Adreno-specifico per i tensori MoEevita il fault).
questo problema (sono richiesti anche solo per far funzionare i modelli
densi, e non sono la causa degli hang MoE - il codice coinvolto negli
hang è diverso, nel path di conversione SOA_Q per tensori quantizzati).
🔴 TERZO PROBLEMA APERTO (2026-07-10): modelli ibridi SSM/MTP (famiglia
Qwen3.5/Qwen3.6) mandano in hang la GPU, indipendentemente dalla dimensione
Dopo aver applicato il fix del work-item-size sopra, ho testato
Qwen3.5-2B-UD-Q2_K_XL(1GB,--no-mmproj, niente MTP attivo) aspettandomiche funzionasse dato che è piccolo — invece ha causato un hang GPU reale
identico a quello dei modelli MoE (
clEnqueueWriteBuffer→CL_OUT_OF_RESOURCESsulla primissima scrittura,
output_norm.weight, prima ancora che qualunquekernel venga lanciato — confermato con instrumentazione che stampa il nome di
ogni tensore appena prima della
set_tensor: una sola riga stampata,poi il crash). Stesso identico comportamento per
Qwen3.6-27B-UD-Q2_K_XL(12GB), sia con
-ngl 0che con-ngl 8.Conferma che non è una questione di dimensione: 1GB e 12GB falliscono
allo stesso identico modo, nello stesso punto. Deve essere qualcosa di
specifico all'architettura.
Ipotesi (non confermata): entrambi i modelli usano un'architettura
ibrida SSM (State Space Model, tipo Mamba) + attention — il file GGUF
contiene tensori
blk.N.ssm_a,ssm_alpha.weight,ssm_beta.weight,ssm_conv1d.weight,ssm_dt.bias,ssm_norm.weight,ssm_out.weightperogni layer, oltre a una testa MTP (
blk.N.nextn.*— multi-tokenprediction/speculative decoding integrata nel modello). Nessuno degli altri
modelli testati con successo (Qwen2.5, granite pre-fix) ha tensori SSM.
Il kernel
ssm_conv(e il correlatogated_delta_net, altra architetturaSSM-like) sono nella lista dei kernel sempre compilati
(
ggml/src/ggml-opencl/CMakeLists.txt) — non ancora verificato se il bug èlì dentro o altrove nella gestione C++ di questi tensori.
Non ancora investigato: quale specifica chiamata OpenCL (probabilmente
async, dato che il fallimento emerge solo alla primissima scrittura
bloccante successiva) avvelena la coda GPU. Servirebbe la stessa
metodologia usata per il bug MoE (instrumentazione mirata + eventualmente
crashdecper il devcoredump) ma applicata a questo caso specifico — nonfatto per esaurimento tempo in questa sessione.
Nota operativa importante: dopo un hang GPU, il sistema resta
degradato — ho riconfermato che ANCHE configurazioni prima funzionanti
(Qwen2.5-1.5B con il fix già applicato) hanno ripreso a fallire subito dopo
aver innescato questi hang SSM/MTP, fino al riavvio del DevKit. Se si
riproduce questo problema, riavviare prima di trarre conclusioni su
qualunque altro test.
Non è un problema generale di "modelli grandi" o di altre famiglie:
testato anche
gemma-4-E2B-it(Gemma 3n, 2.3GB, nessun tensore SSM/MTP,n_embd=1536 — stessa taglia di dimensione che falliva per il bugwork-item-size) su un boot pulito subito dopo i due hang Qwen3.5/3.6: ha
dato un errore completamente diverso, pulito (non un hang), vedi sezione
dedicata subito sotto. Questo conferma che l'hang SSM/MTP è specifico alla
famiglia Qwen3.5/3.6 (o più precisamente ai tensori SSM/nextn), non un
problema architetturale generico che colpisce ogni modello "insolito".
🟡 QUARTO PROBLEMA (2026-07-10, RISOLTO CON WORKAROUND): Gemma 3n e
flash-attention —
CL_INVALID_KERNEL_ARGS, non un hang GPUTestando
gemma-4-E2B-it-UD-Q2_K_XL(Gemma 3n, 2.3GB, nessun tensoreSSM/MTP) con il fix work-item-size già applicato, il caricamento falliva
con un errore diverso da tutti i precedenti:
-54èCL_INVALID_KERNEL_ARGS(non tutti gli argomenti del kernel sonostati impostati correttamente, o uno è invalido) — un rifiuto pulito del
driver, confermato NON essere un hang GPU (contatore hangcheck rimasto
a 0 sia prima che dopo). Causa non ancora identificata nel dettaglio (il
kernel flash-attention ha moltissime varianti compilate a runtime in base
a
DK/DV/BLOCK_M/BLOCK_N, plausibile un bug diclSetKernelArgmancante o non allineato per la specifica combinazione di head-dimension
usata da Gemma 3n).
Workaround verificato: avviando con
--flash-attn off(oLLAMA_ARG_FLASH_ATTN=off), Gemma carica e genera correttamente("2+2" → "4"), nessun hang, nessun crash. Root cause nel kernel FA non
ancora investigata a fondo (fuori scope per questa sessione), ma il
workaround è sufficiente per usare il modello subito.
TL;DR (modelli densi, sezione originale)
-DGGML_OPENCL_USE_ADRENO_KERNELS=OFFconfermato corretto — non èsuperato, resta la scelta giusta (motivo diverso da quello originariamente
ipotizzato nella PR #10693, vedi sotto).
vload_halfsui soli file*flat*.cl) è superata: quei file non vengono nemmeno compilati conADRENO_KERNELS=OFF(vedi analisi CMakeLists sotto), quindi la patch erainnocua ma inutile. Va rimossa e sostituita dalle 3 patch mirate qui
sotto, che coprono i file realmente compilati ed eseguiti.
(
clBuildProgramsu tutti i 150 kernel) sia a runtime (inferenza reale suGPU, output numericamente corretto) — ma solo per modelli densi, vedi
aggiornamento critico sopra per i modelli MoE.
compilano ma leggono memoria male, o che il driver rifiuta a metà) su
questo Mesa/rusticl ancora sperimentale può causare riavvio dell'intero
DevKit, non solo crash del processo — successo più volte durante questo
lavoro. Vedi sezione "Nota sicurezza hardware" più sotto E l'aggiornamento
critico in cima al file.
Perché
GGML_OPENCL_USE_ADRENO_KERNELS=OFFè la scelta giustaAnalisi di
ggml/src/ggml-opencl/CMakeLists.txt: la flag NON controllaquali kernel
.clvengono compilati ed embeddati (conGGML_OPENCL_EMBED_KERNELS=ON) — la listaGGML_OPENCL_KERNELSincludeSEMPRE tutti i kernel
_flat,_noshuffle,_moe/_ns, indipendentementedal flag. L'unica eccezione è
gemm_xmem_f16_f32_os8, aggiunto alla listasolo se
ADRENO_KERNELS=ON(CMakeLists.txt righe 213-215).Quello che il flag controlla davvero è quale codice C++ in
ggml-opencl.cppviene compilato (#ifdef GGML_OPENCL_USE_ADRENO_KERNELS):un blocco enorme (righe ~3199-4123) che copre TUTTA la build/dispatch di
gemv_noshuffle_*,gemm_noshuffle_*,gemm_moe_*_ns,gemv_moe_*_ns,gemm_xmem_f16_f32_os8. ConADRENO_KERNELS=OFFquesto blocco è esclusodalla compilazione: i file
.clcorrispondenti restano innocuamenteembeddati come stringhe header ma non vengono mai passati a
clBuildProgram, quindi non vengono mai eseguiti sul device.Questo è rilevante perché 7 kernel
gemm_moe_*_ns.cl+ 1gemm_xmem_f16_f32_os8.clnon compilano affatto su Mesa/rusticl (vedisotto) — con
ADRENO_KERNELS=ONquesto causerebbe un crash fataleall'avvio del server (o al primo uso, per i moe) nel momento in cui
clBuildProgramfallisce confatal=true. ConOFFil problemasemplicemente non si presenta, perché quel codice non viene mai eseguito.
Le famiglie di kernel "standard" (
mul_mv_id_*per il routing MoE,mul_mm_*_l4_lm,mul_mv_*) restano invece SEMPRE compilate/usate(non gated dal flag), e sono quelle effettivamente coinvolte nell'inferenza
reale — inclusi i modelli MoE, che usano
mul_mv_id_*per il routing, noni kernel
_nsesclusivi Adreno.I 3 bug di compilazione fixati (sessione 2026-07-09; il 4° bug, quello
sul work-item-size, è descritto sopra ed è di natura diversa - runtime,
non compilazione)
Metodologia: harness standalone in C (
clCreateProgramWithSource+clBuildProgramdiretto su ogni singolo file.cl, con le stesse opzionidi compilazione usate realmente da
ggml-opencl.cpp, incluse le macro-Ddinamiche iniettate per-kernel dove applicabile — es.
SIMDGROUP_WIDTH,DK/DV/BLOCK_M/BLOCK_Nper flash-attention) per isolare rapidamentequali dei 150 kernel falliscono davvero, senza dover riavviare
llama-server(lento, e rischioso vedi sotto) per ogni iterazione.Su 150 file, 22 fallivano la compilazione. Di questi, 19 erano falsi
positivi del test harness (mancavano le macro
-Ddinamiche che il C++reale inietta a runtime — verificato ricompilando con le macro corrette
prese da
ggml-opencl.cppe dalla tabella di tuningfa_tune.h): tutti i 6flash_attn_*.cle tutti i 4gemv_noshuffle_*.clcompilano puliti con lemacro reali.
3 bug erano reali, tutti nel set di kernel sempre compilato
(indipendente da
ADRENO_KERNELS):1.
kernels/mul_mv_q4_k_f32.cl— dereference diretto di puntatore halfdhèglobal half *. Stesso pattern già noto e documentato nella PATCH 4esistente (Mesa/rusticl richiede
vload_half()esplicito, il driverproprietario Adreno permette il dereference diretto). Semanticamente
equivalente (
vload_half(offset, p) == *(p+offset)convertito a float).2.
kernels/mul_mm_q4_k_f32_l4_lm.cl— address space implicito non validosrc0_sè dichiaratoglobal uchar *. Il codice assegnava il puntatore auna variabile locale
char *senza qualificatore di address space (quindidefault
private), cambiando implicitamente lo address space daglobalaprivate— cosa che OpenCL C standard vieta e che Mesa/rusticl segnala comeerrore ("changes address space of pointer"), mentre il compiler Adreno
proprietario evidentemente lo tollera. Non è un bug indotto dalle patch
Mesa: è un'inconsistenza nel sorgente llama.cpp stesso — il file gemello
mul_mm_q5_k_f32_l4_lm.clha lo stesso identico pattern ma con ilqualificatore corretto (
global uchar * scales = ...), confermando che sitratta di una svista upstream, non di un problema di portabilità.
3.
kernels/mul_mv_f16_f32_l4.cl— builtin proprietario Qualcomm applicato per erroreIl file macro-ridefinisce
sub_group_shuffle_xor(la funzione builtinstandard di
cl_khr_subgroup_shuffle, già usata correttamente altrove nelfile) con la variante proprietaria
qcom_sub_group_shuffle_xor, ma lo fasotto
#ifdef ADRENO_GPU— che noi definiamo forzatamente con la PATCH 3esistente (
-D cl_qcom_reqd_sub_group_size) per attivare i rami di codiceche impostano
N_SIMDGROUP/N_DST/ecc. Su hardware Adreno reale condriver proprietario,
ADRENO_GPUdefinito implica sempre anche il supportodi
cl_qcom_subgroup_shuffle; noi però forziamo solo la prima macro, nonla seconda, che Mesa infatti non implementa (verificato via
clinfo: solocl_khr_subgroup_shufflestandard è esposto, non l'estensione proprietariacl_qcom_subgroup_shuffle). Fix: la macro-redefinizione ora richiedeesplicitamente che l'estensione proprietaria sia davvero disponibile, così
su Mesa il codice ricade sulla funzione standard
sub_group_shuffle_xorgià corretta e già usata nel resto del file.
Questo file è nel set di kernel sempre compilato, indipendentemente da
ADRENO_KERNELS— senza questo fix,llama-servercrasha già in fase dicaricamento kernel (
load_cl_kernels()), prima ancora di caricare unmodello.
Bug noti ma NON fixati (fuori scope, irrilevanti con
ADRENO_KERNELS=OFF)Questi kernel falliscono la compilazione su Mesa/rusticl per motivi reali,
non falsi positivi — ma dato che
ADRENO_KERNELS=OFF, il codice C++ che licompilerebbe/userebbe è escluso a compile-time, quindi restano innocui
(file
.clembeddato ma mai passato aclBuildProgram):gemm_moe_{q4_0,q4_1,q5_0,q5_1,q4_k,q5_k,q6_k}_f32_ns.cl(7 file):usano
float32come tipo di variabile (__private float32 reg_c = ...)e swizzle vettoriali estesi fino a
.sv(32 componenti). Questo non èOpenCL C standard (il massimo vettore standard è
float16, swizzle finoa
.sf) — è quasi certamente un'estensione proprietaria del compilerQualcomm per vettori più larghi. Un fix richiederebbe riscrivere ogni
kernel per usare due registri
float16(.lo/.hi) al posto di unsingolo
float32, con ~40 righe da toccare per file e un rimappaggioattento degli indici
s0..sv→lo.s0..sf/hi.s0..sf. Non tentato:rischio alto di bug numerici silenziosi per il beneficio marginale (con
ADRENO_KERNELS=OFFil routing MoE passa comunque damul_mv_id_*, checompila ed esegue correttamente, vedi test granite sotto).
gemm_moe_mxfp4_f32_ns.cl: stesso problemafloat32più un mismatchdi rank tra
half8efloatscalare in 4 punti — probabilmentecorrelato allo stesso pattern di refactor necessario sopra.
gemm_xmem_f16_f32_os8.cl: usa builtin Qualcomm genuinamenteproprietari senza equivalente standard (
qcom_get_physical_sub_group_id,qcom_sub_group_constant_load8,qcom_sub_group_sync,QCOM_CLK_CONST_LOAD_SYNC). Non fixabile senza il driver proprietario;questo è l'unico file la cui embedding dipende davvero da
ADRENO_KERNELS(vedi sopra), quindi conOFFè semplicemente escluso.Se in futuro si vuole tentare
ADRENO_KERNELS=ONper inseguire leperformance dei kernel "_ns"/flat ottimizzati, questi bug vanno risolti
prima — altrimenti il server crasha al boot (kernel sempre compilati
eagerly in
load_cl_kernels_adreno).Nota sicurezza hardware (importante per chi ripete il lavoro)
Durante questo lavoro il DevKit si è riavviato più volte (crash-loop con
boot da pochi minuti l'uno) esattamente nel momento in cui venivano
eseguiti kernel OpenCL (non solo compilati) contenenti i bug sopra — in
particolare il bug #1 (
vload_halfmancante) causa una lettura di memorianon valida quando il kernel viene davvero eseguito sull'hardware, non
solo compilato. Su un driver Mesa/Freedreno ancora sperimentale come
questo, un accesso di memoria non valido da parte della GPU può bloccare
il driver kernel-space abbastanza da far scattare un watchdog reset
dell'intero sistema, non solo un crash del processo
llama-server.Compilare (
clBuildProgram) senza mai eseguire (clEnqueueNDRangeKernel)è invece risultato sempre sicuro nei test — utile saperlo se si vuole
verificare rapidamente nuovi kernel senza rischiare un riavvio.
Consiglio: dopo aver applicato queste patch e PRIMA di lanciare
llama-server -ngl 99con un modello nuovo/quantizzazione nuova, verificareprima con un harness di solo-compile (vedi
.clcheck.cnon incluso qui mabanale da riscrivere:
clCreateProgramWithSource+clBuildProgramcon lestesse opzioni di
ggml-opencl.cpp) che tutti i kernel coinvolticompilino, prima di eseguire davvero.
Modelli testati
--flash-attn offPerformance (Qwen2.5-0.5B Q4_K_M, stesso prompt "What is 2+2?", CPU vs GPU):
dispatch OpenCL dominante — non rappresentativo per modelli più grandi,
ma non è stato possibile completare un confronto su un modello denso
medio/grande dato che gli unici modelli grandi disponibili nella cache
locale sono tutti MoE o SSM/MTP, entrambi ancora non funzionanti su GPU)
⚠️ Su questo modello minuscolo (0.5B) la CPU genera più veloce della
GPU — atteso: l'overhead di dispatch OpenCL domina su un modello così
piccolo. Non è indicativo delle prestazioni relative su modelli più grandi
(dove la GPU dovrebbe vincere nettamente), ma non sono riuscito a
completare il test con un modello più grande/MoE/IQ4_NL in questa sessione
prima di dover consegnare questo file — vedi "Cosa manca" sotto.
Cosa manca (da fare nella prossima sessione)
trovato rapidamente un modello piccolo con quant IQ4_NL disponibile su HF
(bartowski et al. tendono a pubblicare IQ4_XS invece); i repo con
IQ4_NL trovati erano quasi tutti modelli 7-8B, più lenti da iterare.
granite-3.0-1b-a400meQwen3.6-35B-A3B),risultato: hang GPU reale, vedi "AGGIORNAMENTO CRITICO" in cima al file.
Serve
crashdec(tool Mesa insrc/freedreno/decode/, non buildato pertempo) per identificare il comando GPU esatto che causa il fault, poi
capire se è nel path di conversione SOA_Q generico per tensori 3D
(ipotesi principale) o altrove.
realistica (es. 3-8B denso), dove il vantaggio della GPU dovrebbe essere
visibile (sul modello 0.5B testato la CPU vince, ma non è rappresentativo).
Non fatto per esaurimento tempo dopo l'indagine sugli hang MoE.
Modifiche da riportare nel Containerfile
Sostituire la PATCH 4 esistente (script Python
vload_halfsui file*flat*.cl) con il diff completo qui sotto (identico al contenuto diopencl-mesa-rusticl.patchaccanto a questo file, applicabile congit applydirettamente sul checkout in/build/llama.cpp). Include siai 3 fix di compilazione della sessione 2026-07-09 sia il fix del
work-item-size della sessione 2026-07-10. Le PATCH 1/2/3 esistenti nel
Containerfile restano necessarie e corrette così come sono (il diff qui
sotto le ri-applica comunque, essendo un diff completo su
ggml-opencl.cpp).