Dacă rulezi un model local și vrei răspunsuri mai rapide fără să schimbi complet stack-ul, speculative decoding merită atenție. Ideea de bază este simplă: un model mai mic sau un mecanism auxiliar propune câțiva tokeni în avans, iar modelul principal îi verifică. Când propunerile sunt bune, modelul mare validează mai mulți tokeni într-o singură trecere și scade latența totală.
De ce poate funcționa? Documentația Hugging Face despre speculation explică faptul că inferența LLM este adesea limitată de memorie, nu doar de calcul. Cu alte cuvinte, nu câștigi neapărat pentru că „muncești mai puțin”, ci pentru că reduci numărul de pași costisitori ai modelului principal. Tot aceeași documentație notează că, atunci când ghicirile sunt suficient de bune, accelerarea poate ajunge la 2-3x, iar pentru sarcini de tip cod poate fi chiar mai mare.
Ce variantă alegi pentru implementare
În practică, ai două direcții utile. Prima este modelul draft: un model mai mic, compatibil, care propune tokenii înaintea modelului principal. A doua este speculation pe bază de n-gram sau Medusa, dacă runtime-ul tău o suportă.
În Text Generation Inference, documentația oficială spune clar că sunt suportate două metode principale: Medusa și n-gram. Pentru n-gram, activarea se face prin parametrul –speculate. Este o metodă simplă și utilă mai ales pentru cod sau text repetitiv, tocmai pentru că încearcă să reia continuări deja văzute în secvență.
În llama.cpp există un exemplu dedicat pentru speculative decoding, iar lista de argumente arată opțiuni precum –spec-draft-hf și –spec-draft-n-max. Asta îți spune două lucruri importante: există suport explicit pentru un draft model și poți controla câți tokeni sunt propuși înainte de verificare.
Condiția pe care nu ar trebui să o ignori
Cea mai importantă regulă practică vine din articolul Hugging Face despre assisted generation: modelul asistent trebuie să aibă același tokenizer ca modelul principal. Dacă nu respecți această condiție, apar conversii suplimentare și costuri care pot anula beneficiul.
Mai există și un al doilea criteriu: modelul draft trebuie să fie suficient de mic încât să fie rapid, dar suficient de apropiat de modelul mare încât să nu greșească prea des. Dacă draft modelul este lent sau ratează multe propuneri, speculative decoding poate produce beneficii mici sau chiar regres.
Cum implementezi fără să te păcălești singur
Începe cu un baseline curat. Rulează modelul principal fără speculative decoding și notează valorile. Apoi activezi speculation și repeți exact aceleași teste.
Ce trebuie să păstrezi identic între rulări:
prompturile;
cuantizarea;
setările de context;
numărul maxim de tokeni generați;
temperatura;
seed-ul, dacă îl poți fixa;
offload-ul pe GPU și orice parametru relevant de batch.
Dacă folosești llama.cpp, ideea generală este să rulezi modelul principal prin exemplul dedicat speculative decoding și să setezi un draft model compatibil, apoi să testezi valori prudente pentru numărul de tokeni propuși, de exemplu 4 sau 8. Dacă urci prea sus din prima, costul verificării poate crește mai repede decât beneficiul.
Dacă folosești TGI și nu ai un model Medusa, poți porni cu n-gram speculation și un parametru modest pentru –speculate. Documentația spune clar că această metodă funcționează mai bine pentru cod sau text repetitiv, deci nu e corect să judeci rezultatul doar pe un benchmark creativ de tip chat liber.
Ce metrici merită urmărite
Nu compara doar impresii. Măsoară separat:
TTFT, adică timpul până la primul token;
latența totală a răspunsului;
tokeni pe secundă;
p50 sau p95, dacă faci mai multe rulări;
rata de acceptare a tokenilor draft, dacă runtime-ul o expune.
Aici apare diferența dintre „pare mai rapid” și „este mai rapid”. Poți avea un caz în care latența totală scade, dar TTFT crește. Pentru un chatbot interactiv, asta contează. Pentru generare mai lungă, poate conta mai mult viteza medie pe tot răspunsul.
O formulă simplă pentru raport este:
câștig procentual = (latență baseline – latență speculativă) / latență baseline × 100
Cum arată un test corect
Fă 3-5 rulări de încălzire, apoi cel puțin 10 rulări reale pentru fiecare configurație. Separă prompturile pe tipuri: întrebări scurte, rezumate, completări tehnice, cod. Assisted generation și speculation merg, de regulă, mai bine când ieșirea este mai predictibilă. Hugging Face notează și că temperaturile mici ajută, pentru că modelul asistent greșește mai rar.
Concluzia practică este simplă: speculative decoding nu se activează „din auzite”, ci după un benchmark curat. Dacă ai tokenizer compatibil, un draft model suficient de bun și un set de prompturi potrivit, poți obține un câștig real de latență pe un model local. Dacă nu, rezultatul poate fi modest. De aceea, decizia corectă nu este să cauți cea mai spectaculoasă promisiune, ci să măsori riguros TTFT, latența totală și tokenii pe secundă în propriul tău setup.
Surse
- https://github.com/ggml-org/llama.cpp/tree/master/examples/speculative
- https://raw.githubusercontent.com/ggml-org/llama.cpp/master/common/arg.cpp
- https://huggingface.co/docs/text-generation-inference/conceptual/speculation
- https://huggingface.co/blog/assisted-generation
- https://huggingface.co/docs/text-generation-inference/basic_tutorials/train_medusa

















































