Знакът на КАГАМИ КАГАМИ
kagami.bg/academy · lesson · machine-readable viewUPDATED 2026-10-03 · NOT TESTED
IDENTITY
module
GX10-04-15 · Speculative decoding with a separate draft model
series
GX10 (local AI server class: NVIDIA GB10, e.g. ASUS Ascent GX10 / DGX Spark)
level
Intermediate
duration
30 min
prerequisites
A GB10-class machine with a working SGLang or vLLM environment for ARM64 and CUDA (installation not covered); two models of the same family with a shared vocabulary
trust_label
UPDATED 2026-10-03 (commands checked against the current SGLang, vLLM and NVIDIA DGX Spark documentation) · NOT TESTED (no GB10 machine available; no commands run; no speed-up measured)
language
human view: bg · english edition: /en/academy/gx10/ (same file name)
previous / next
GX10 series index / GX10 series index · related: 04-10_vLLM_Inference.html
PURPOSE

Explain speculative decoding (a small draft model proposes tokens, the large target model verifies them in one forward pass), show how to enable it with a separate draft model in SGLang (STANDALONE) and vLLM (draft_model), and give a script to measure tokens per second before and after on the reader's own machine. No speed-up figures are asserted; the reader measures them.

KEY CONCEPTS
COMMANDS / PATHS
CHECKLIST
NEXT MODULE

GX10 series index: kagami.bg/academy/gx10/ · related: 04-10 vLLM (04-10_vLLM_Inference.html) · offer: Quick experiment (kagami.bg/stalbata/)

SOURCES
TAGS
gx10nvidia-gb10speculative-decodingsglangvllminferencebenchmarking
ОБНОВЕНО · 03.10.2026

Спекулативно декодиране на GX10: по-бърз изход от модела

Малък модел „чернова“ познава няколко думи напред, а големият ги проверява наведнъж. По документацията на vLLM изходът остава със същото разпределение, но се получава по-бързо — стига черновата да познава достатъчно често. Тук разбираш как работи, пускаш го в SGLang и vLLM и го измерваш на своята машина, вместо да вярваш на обещани кратности.

⏱ 30 мин Средно GX10 NVIDIA GB10 · 128 GB обща памет · 273 GB/s SGLang · vLLM
SGLang · vLLM🔒 локално Модели Qwen (отворени тегла)🔒 локално Теглене на модели от Hugging Face🌐 глобален
🔄
ОБНОВЕНО · 03.10.2026 — какво
Урокът е преработен по текущите документи на SGLang и vLLM. Махнахме: таблицата с „1,5–2,5ד и другите кратности (нямаме измервания на GB10 и не можем да ги подкрепим), твърдението „от версия 0.3“, остарелия флаг --speculative-draft-model (сега алгоритъмът се избира с --speculative-algorithm), старите vLLM ключове speculative_model и num_speculative_tokens на най-горно ниво (в документацията са заменени от speculative_config), примерите с Llama (изискват приемане на лиценз при теглене) и неподкрепената цифра „~40 GB“, както и --host 0.0.0.0. Добавихме: преглед на методите (отделна чернова, EAGLE, MTP, n-gram), изчисление на паметта, скрипт за честно измерване преди и след, ограниченията от документацията (версии на vLLM, паралелизъм) и честното „кога не помага“. Примерите с модели са от документацията на двата проекта.
⚠️
Какво не сме пускали сами
При проверката нямахме машина от класа GB10. Командите са сверени с официалните документи, но не са пускани — затова няма етикет „ТЕСТВАНО“ и няма измерени ускорения. Не са пускани и скриптът за измерване, и инсталирането на SGLang или vLLM за ARM64 и GB10 (то не е част от този урок — виж документацията им и плейбуковете на NVIDIA).

01Какво ще научиш

02Преди да започнеш

КаквоСтойност
Памет128 GB LPDDR5x, обща за процесора и видеокартата (NVIDIA)
Честотна лента на паметта273 GB/s (NVIDIA)
Пример: голям модел + чернова (vLLM)Qwen3-8B + Qwen3-0.6B — от документацията на vLLM
Пример: голям модел + чернова (SGLang)Qwen2.5-7B-Instruct + Qwen2.5-1.5B-Instruct — от документацията на SGLang
Приблизителен размер на теглата в bf16около 2 байта на параметър: 8 милиарда ≈ 16 GB, 0,6 милиарда ≈ 1,2 GB — плюс кеш за контекста
💡
Защо честотната лента има значение
При генериране дума по дума всяка нова дума изисква да се прочетат теглата на модела от паметта. Затова, по принцип, скоростта често се ограничава от паметта, а не от изчисленията — и проверката на няколко думи наведнъж е изгодна: един проход през теглата проверява цялата партида. ⚠️ Това е общият принцип; ние не сме го измервали на GB10.

03Стъпки

  1. Как работи

    Две роли. Черновата (малък, бърз модел) предлага няколко следващи думи. Целевият модел (големият) проверява всички предложени думи с един проход. Приетите се запазват; на първата отхвърлена целевият модел слага собствената си дума и цикълът започва отново. Така големият модел определя изхода, а черновата само му спестява проходи.

    Стъпка (измислен пример)Какво става
    Чернова предлага 5 думи„Столицата на България е Варна“
    Целевият модел проверяваПървите 4 са приети, 5-ата („Варна“) е отхвърлена
    Резултат от един проход4 приети думи + 1 дума от целевия модел („София“) = 5 думи за цената на един проход през големия модел
    ✅
    Качеството не бива да страда
    Документацията на vLLM описва спекулативното вземане на проби като теоретично без загуба, до границите на числовата точност на хардуера. Изходът може леко да се различава от пуск до пуск и по други причини (например размер на партидата).

    Колко печелиш зависи от честотата на приемане: колко от предложените думи големият модел приема. Ако черновата често греши, проверките се пилеят и печалбата изчезва.

  2. Избери метод

    Този урок показва най-простия — отделен малък модел като чернова. Има и други, които обикновено изискват специално обучена глава или вградена поддръжка в модела.

    МетодКакво му трябваБележка (по документацията)
    Отделна черноваМалък модел със същия речникSGLang: STANDALONE; vLLM: draft_model. Най-лесен за начало
    EAGLE / EAGLE-3Специално обучена „чернова-глава“ за твоя моделSGLang го препоръчва за най-добро съотношение скорост/качество, когато има такава глава
    MTPМодел с вграден многотокенов предикторСамо за модели, които го поддържат
    N-gramНищо допълнителноБез втори модел; в SGLang — само CUDA. Печалбата е скромна
  3. Измери базовата скорост (без чернова)

    Първо стартирай сървъра без спекулативно декодиране (обикновената команда на SGLang или vLLM за същия голям модел), после пусни скрипта. Той праща три еднакви заявки при температура 0 и три при температура 0,7, отхвърля първия (загряващ) отговор и записва медианата на токени за секунда и текста на отговорите.

    python · bench.py
    import json, os, statistics, sys, time
    from openai import OpenAI
    
    # SGLang слуша по подразбиране на порт 30000, vLLM — на 8000
    BASE_URL = os.environ.get("LLM_BASE_URL", "http://127.0.0.1:8000/v1")
    LABEL = sys.argv[1] if len(sys.argv) > 1 else "run"
    PROMPTS = [
        "Explain in five sentences how a hash table works.",
        "Write a Python function that merges two sorted lists, with comments.",
        "List ten steps for backing up a PostgreSQL database.",
    ]
    
    client = OpenAI(base_url=BASE_URL, api_key="EMPTY")
    model = client.models.list().data[0].id
    
    def ask(prompt, temperature):
        t0 = time.perf_counter()
        r = client.chat.completions.create(
            model=model, temperature=temperature, max_tokens=256,
            messages=[{"role": "user", "content": prompt}],
        )
        dt = time.perf_counter() - t0
        return r.usage.completion_tokens / dt, r.choices[0].message.content
    
    ask(PROMPTS[0], 0)  # загряване — отговорът се отхвърля
    result = {}
    for temp in (0, 0.7):
        speeds, texts = [], []
        for p in PROMPTS:
            tps, text = ask(p, temp)
            speeds.append(tps)
            texts.append(text)
        result[str(temp)] = {"median_tok_s": round(statistics.median(speeds), 1), "texts": texts}
        print(f"температура {temp}: медиана {result[str(temp)]['median_tok_s']} токена/с")
    
    with open(f"out_{LABEL}.json", "w", encoding="utf-8") as f:
        json.dump(result, f, ensure_ascii=False, indent=2)

    Пусни го така: python bench.py without. Скоростта включва и прочитането на заявката, но тя е еднаква преди и след, затова сравнението е честно. ⚠️ Скриптът не е пускан от нас.

  4. SGLang: отделна чернова

    Алгоритъмът се избира с --speculative-algorithm STANDALONE, а черновата — с --speculative-draft-model-path. Примерът е от документацията на SGLang; ние добавихме само --host и --port, за да не слуша сървърът към цялата мрежа.

    bash · на машината
    python3 -m sglang.launch_server \
        --model Qwen/Qwen2.5-7B-Instruct \
        --speculative-algorithm STANDALONE \
        --speculative-draft-model-path Qwen/Qwen2.5-1.5B-Instruct \
        --speculative-num-steps 4 \
        --speculative-eagle-topk 2 \
        --speculative-num-draft-tokens 7 \
        --mem-fraction-static 0.7 \
        --cuda-graph-max-bs-decode 8 \
        --host 127.0.0.1 --port 30000
    • --speculative-num-steps — колко пъти черновата предлага последователно (дълбочина).
    • --speculative-eagle-topk — колко кандидата разглежда на всяка стъпка.
    • --speculative-num-draft-tokens — колко токена се проверяват наведнъж.
    • Документацията на SGLang (в раздела за EAGLE) съветва тези три параметъра да се задават заедно или изобщо да не се задават, за автоматична настройка. Подразбиращите се стойности за STANDALONE са 3, 1 и 4.
    ⚠️
    Ограничение
    Според документацията на SGLang, STANDALONE към момента не поддържа DP attention (--attn-dp-size над 1). Пусни bench.py с LLM_BASE_URL=http://127.0.0.1:30000/v1.
  5. vLLM: отделна чернова

    Всички настройки на спекулативното декодиране се подават в --speculative-config като JSON. Старите отделни флагове (--speculative-model, --num-speculative-tokens) са обявени за остарели.

    bash · на машината
    vllm serve Qwen/Qwen3-8B \
        --host 127.0.0.1 --port 8000 \
        --speculative-config '{"method": "draft_model", "model": "Qwen/Qwen3-0.6B", "num_speculative_tokens": 5}'

    Същото в Python, без сървър (по документацията на vLLM):

    python
    from vllm import LLM, SamplingParams
    
    llm = LLM(
        model="Qwen/Qwen3-8B",
        tensor_parallel_size=1,
        speculative_config={
            "method": "draft_model",
            "model": "Qwen/Qwen3-0.6B",
            "num_speculative_tokens": 5,
        },
    )
    out = llm.generate(["The future of AI is"], SamplingParams(temperature=0.8, top_p=0.95))
    print(out[0].outputs[0].text)
    ⚠️
    Версии и ограничения от документацията
    Според vLLM, спекулативно декодиране с черновен модел не се поддържа във версии до 0.10.0, а паралелизмът по конвейер (pipeline parallelism) не се комбинира с него във версии до 0.15.0. Провери версията си. Друг речник между черновата и големия модел е възможен само с опцията use_heterogeneous_vocab и засега само при „greedy“ предлагане на чернова.
  6. Измери отново и сравни

    Спри сървъра, пусни го със спекулативното декодиране и повтори python bench.py with. Сравни двата файла out_without.json и out_with.json.

    • Скорост: медианите при температура 0 и при 0,7. Повтори пуска няколко пъти — единичен пуск не е доказателство.
    • Текст: при температура 0 отговорите трябва да са еднакви или почти еднакви. По документацията на vLLM малки разлики са възможни заради числова точност и размер на партидата.
    • Честота на приемане: vLLM има страница за метрики на приемане по заявка — виж „Източници“. Ако честотата е ниска, пробвай друга чернова или друга дължина на предлагане.
    Моите числаБез черноваС чернова
    Температура 0, токени/с——
    Температура 0,7, токени/с——
    Допълнителна памет——
  7. Кога не помага

    • Черновата често греши. Друго семейство, много по-слаб модел или различна задача намаляват приемането. По принцип по-висока температура също го намалява — затова мери и при твоята температура. ⚠️ Не сме го мерили на GB10.
    • Кратки отговори. Малко токени — малко за печелене.
    • Голямо едновременно натоварване. Допълнителният модел и проверките са допълнителна работа; при много паралелни заявки ползата може да се стопи. Мери при реалното си натоварване.
    • Допълнителна памет. Черновата и нейният кеш заемат място в общата памет, която делят и системата, и големият модел.

    Ако не видиш печалба в твоите числа — не го ползвай. Измереното е по-важно от обещаното.

04Проверка

Тест

1. Какво прави големият (целевият) модел с думите, предложени от черновата?

2. Защо черновата трябва да е от същото семейство като големия модел?

3. Как се измерва честно дали спекулативното декодиране помага?

4. Какво казва документацията на vLLM за качеството на изхода?

05Какво следва

06Източници

  1. SGLang: Speculative Decoding 🔒 локално — методи, STANDALONE, параметри и ограничения.
  2. vLLM: Speculative Decoding · Draft Models 🔒 локално — --speculative-config, гаранции за качество, известни несъвместимости.
  3. vLLM: метрики на приемане по заявка — как да видиш честотата на приемане.
  4. NVIDIA DGX Spark: хардуер — 128 GB обща памет, 273 GB/s.
  5. Chen и др.: Accelerating Large Language Model Decoding with Speculative Sampling — основната работа, на която се позовава vLLM.
  6. Qwen3-8B 🌐 глобален — страница на модела с лиценза му.