Skip to content

hal0 v1.5.0

Latest

Choose a tag to compare

@github-actions github-actions released this 19 Oct 21:36
· 46 commits to main since this release
665545b

Highlights

  • Speculative-decoding drafters. A model can carry a small drafter file
    (-LiLiCorr, -DFlash, -DFlash2, -DSpark, -EAGLE3, -draft) that
    llama-server checks in one pass, so replies come faster with the same
    output. Add from Hugging Face finds and fit-checks drafters before anything
    downloads, the model drawer has a Drafter field, and a rescan pairs a
    fitting drafter it finds beside a model. (#2765, #2768, ADR-0031)
  • A slot now tells llama-server which device to use. The slot layer
    passes --device from the slot's selected device, so a runner image that
    lists both ROCm and Vulkan for one GPU no longer splits every model across
    both backends and no longer leaves an idle GPU at 100 % busy. (#2772)
  • Add from Hugging Face lists quants, not files. One row per quant, split
    GGUFs pulled whole, the projector and drafters offered beside the quant.
    (#2760)
  • Compact, consistent model pickers. Fit icon plus GB figure in every
    state, modality glyphs after the name, runtime as a chip, two-line rows.
    (#2762, #2771, #2773)
  • Runner images move to llama.cpp b11716 (standard, cpu, cuda), past
    the b11669 floor the LiLiCorr drafter kind needs. (#2763)

Added

  • Speculative-decoding drafters. A model can now carry a drafter, a small
    file that proposes tokens the main model checks in one pass, so replies
    come faster with the same output. Add from Hugging Face lists drafters found
    in the repo or in a companion repo by the same author (-LiLiCorr,
    -DFlash, -DFlash2, -DSpark, -EAGLE3, -draft) and checks that the
    drafter fits the quant from the two file headers before anything downloads;
    hal0 model pull <id> --draft <file> [--draft-repo <repo>], hal0 model add --draft <path> and hal0 model set <id> --draft <path|none> do the same
    from the terminal, the model drawer has a Drafter field, and a rescan pairs
    a fitting drafter it finds beside a model (one you unpair on purpose stays
    unpaired). A paired drafter is used before the model's own MTP heads. A
    drafter the runner image is too old to run (LiLiCorr needs llama.cpp
    b11669 or newer) is reported on the slot instead of crashing the launch, and
    each slot reports its draft acceptance rate. DELETE /api/models/{id}/draft removes the file; POST /api/models/inspect-draft
    checks a pair. The benchmark with/without comparison comes in a later release.

Breaking

  • The profile field mtp is now speculation (auto, off or ngram).
    hal0 update rewrites profiles.toml once: mtp = "off" becomes
    speculation = "off" and mtp = "auto" is dropped, after copying the file
    to profiles.toml.bak-<UTC stamp> beside it. After that the API, the CLI
    (--mtp, which exits 2) and the MCP tools refuse mtp on a profile with a
    422 profiles.field_renamed that names speculation; there is no alias.
    The model's own mtp fact (the file has MTP heads) is unchanged. A profile
    may no longer carry --spec-type in its flags (hal0 derives it from the
    model's drafter or heads); the update removes one it finds, turning an
    ngram-* value into speculation = "ngram". Rolling back to 1.4.x
    quarantines every profile that carries speculation: restore the
    profiles.toml.bak-<UTC stamp> copy before hal0 update --rollback (see
    the rollback guide).

Changed

  • Model picker rows are compact and consistent. In the slot drawer and
    the inference cards, the fit estimate now shows as an icon plus the GB
    figure in every state (a check, an exclamation mark or an X; hover for
    "fits", "tight" or "won't fit"). Vision models carry an eye glyph instead of
    the word. Each dropdown row is two lines: the name and modality on top,
    then quant, size and fit. "Used by N slots" left the row; it stays in the
    model drawer's Used-by panel.

  • Add from Hugging Face lists quants, not files. Inspecting a repo now
    shows one row per quant (UD-Q4_K_XL, Q8_0, …) with its total size. A
    split GGUF (…-00001-of-00003.gguf, usually in a per-quant folder) is one
    row, and pulling it downloads every part into the model's directory under
    names llama.cpp can open, so the slot loads the whole model from the
    first part. The vision projector is offered beside the quant instead of
    among them, and speculative-decoding draft files are listed separately (and
    pairable: see Added).
    POST /api/models/inspect returns projectors under mmproj and drafters
    under drafts; variants now holds only quants.

Fixed

  • The text-to-speech selection now names the engine that actually runs. A fresh install showed llama-server as the voice.tts provider, and after switching the device (CPU to GPU or back) the selection and tts.toml kept the previous engine's name, so the dashboard could offer Kokoro voices for a Qwen3-TTS engine. The provider is now always derived from the device (kokoro on CPU, qwen3tts on a ROCm GPU), on read and on every apply. A Vulkan GPU keeps Kokoro, and tts.toml now gets the kokoro profile there too: the Qwen3-TTS runner is ROCm-only, and a written qwen3-tts profile is not swapped to Kokoro at launch (#2749).

  • A slot now tells llama-server which device to use. The slot layer passes --device from the slot's device (ROCm0, Vulkan0, CUDA0, or none for a CPU slot). Before, a runner image that lists both ROCm and Vulkan for the same GPU split every model across both backends; each idle server then held compute queues on both, and with two or more slots loaded the GPU sat at 100 % busy and full clock around the clock (#2767).

  • A paired DFlash or EAGLE-3 drafter no longer aborts the slot at load. The slot layer pinned the drafter to one device while the model itself was free to span every device the runner sees, and those drafter kinds borrow the model's embedding and output tensors, so llama-server stopped with pre-allocated tensor (output.weight) in a buffer ... that cannot run the operation. A drafter file now follows the model's devices; only embedded MTP heads still get --spec-draft-device (ADR-0031, amended) (#2766).

  • The slot card's model picker no longer shows the file size twice. Each
    row listed the model's size as plain text right beside the fit chip, which
    already reads ~N GB. The plain figure is gone; the fit chip stays, and the
    model drawer's facts band still shows the exact size.

  • Model picker rows: bare modality glyphs, runtime as a chip. The eye
    (vision) and bolt (drafter) glyphs no longer wear a chip box; they follow
    the model name directly, ahead of the quant and fit chips, on both the open
    list and the closed trigger. The runtime named on a row's second line is a
    chip too, purple for the NPU runtime (flm) to match the device chips.

  • hal0/utility, hal0/brain, hal0/npu and hal0/<slot> load their own
    slot when it is cold.
    A slot with a bound model counted for its virtual
    name only while that model was already loaded, so a cold utility fell
    through to agent and every Hindsight extraction call cold-loaded the
    largest model on the box. The slot the name points at is now loaded on
    demand, NPU (FLM) slots included; agent is used only when no slot in the
    chain has a model bound. Each substitution is logged as resolver.fallback
    (ADR-0023, amended) (#2741).

  • Deleting a memory by an observation id now works instead of silently
    doing nothing.
    Search, the units list and the brain's memory_search
    hand out an observation's own id, but POST /api/memory/delete and the
    memory_delete tool answered {"deleted": 0} for it, even for the owning
    agent. An observation has no document of its own, so its id now deletes the
    one document it was derived from, which removes the observation with it.
    An observation derived from more than one document is refused with
    memory.delete.observation_multi_source, which lists those document ids:
    a single-id delete runs without approval, so it never removes several
    documents at once, and deleting the listed ids together goes through the
    usual bulk-delete approval (#2747).