Skip to content

Releases: 0xBakeer/TandemLLM

TandemLLM 0.12.0

Choose a tag to compare

@0xBakeer 0xBakeer released this 19 Oct 09:56

TandemLLM 0.12.0 gives API clients that offer tools a conductor profile of their own. An OpenAI SDK, curl or an unnamed client that sends tools and names no profile now gets tools: the prompt as the client sent it, token for token the raw path's, with the loop guards and the tool-call checks acting. Every change is in CHANGELOG.md, and the PDF below is the manual.

Tool calls

  • The tools profile. A request resolves to the X-Tandem-Profile header, else the profile mapped to its client, else tools when no profile maps the client and the request offers a function tool. It adds no note, package, memory or effort change. D1, D1b, D2, E1, C3, C4 and C5 act, and each act is journaled. A call goes out whole once the checks have seen it.
  • Structured outputs with tools. A response_format or structured_outputs beside tools was a 400. The answer is now a tool call or the document, and the model's own first answer token picks which. Speculation changes no token.
  • C5, one mutation per turn. An answer with two or more calls that change something outside the conversation (send, schedule, create, write, delete) is written again one call at a time, each after the last one's result. It acts in tools and journals in shadow in coding, chat-app, hermes and chat.
  • The secret echo mask. A key that a tool result showed the model is masked where the answer repeats it: sk-abc123 becomes sk-[redacted]. Call arguments are untouched.
  • On the raw path an SDK, curl or unnamed client gets the thinking in reasoning_content and the answer alone in content.

tool-eval-bench

We ran tool-eval-bench on one DGX Spark with Qwen3.8-27B in the EXL3 6.0 pack, seed 42, temperature 0, each row one run. On the 69 scenarios:

path score time
raw, thinking off 92 8.0 min
raw, effort low 96 12.7 min
raw, effort medium 96 13.4 min
raw, effort high 95 11.9 min
raw, effort xhigh 97 12.4 min
conductor, tools 95 15.0 min
conductor, effort by turn class, no packages 96 13.5 min
conductor, effort by turn class, packages 94 26.0 min
conductor, chat 91 28.0 min

Two runs of the same prompt scored 95 and 97, so rows within 2 points are the same. In the bench's hard mode, 28 scenarios, the conductor scored 91 and raw 84, one run a side. docs/tool-eval-bench.md has every row with its settings and command, and docs/benchmarks.md says how to run the bench.

Fixes

  • /v1/models/{id} asks for the key /v1/models asks for. The standalone proxy times out a request that sends nothing for 60 s. chatd compacts and retries once on a 400 that says the request is over the window. An operator sets a relayed model's output limit under Backends (#21).
  • Pull requests #36, #46, #47, #49, #50, #51, #53 to #61, #64, #67, #70, #71 and #73 to #76 by AgentSparko fix the conductor's journal writer and session pages, the collectors, the proxy's TLS sockets and model cards, the sandbox relay, chatd's finish_guard, and stale responses in the dashboard.

Update

Run the installer again: bash ~/TandemLLM/src/install.sh --yes --ref v0.12.0. A box with stored conductor documents gets the tools profile at its next start; a stored monitor document gets C5 with tools/monitor_migrate.py --put http://127.0.0.1:8000 --tasks C5, run on the box.

TandemLLM 0.11.4

Choose a tag to compare

@0xBakeer 0xBakeer released this 18 Oct 10:04

TandemLLM 0.11.4 adds Agents mode to the Chat tab. The main agent plans with you and hands every file write and every multi-step build or fix to a worker, so the file texts live in the worker's context and leave with it. The engine keeps the worker's and the parent's cache rows while they take turns: in the live checks, no worker call after the first read its prompt from 0. Every change is in CHANGELOG.md, and the PDF below is the manual.

Agents mode

  • A chat setting, agents, off by default. The composer's agents chip turns it on for one chat, and the settings switch sets the default for new chats. In a chat with messages the switch first says how many tokens the next message reads again.
  • The main agent gets a task tool. Each call starts a worker: a full run on a hidden conversation that sees the task, its brief, the todo list and your message, and nothing else of the chat. The worker uses the chat's sandbox and files and makes at most 40 calls; a run starts 8 tasks at most.
  • In Agents mode the main agent reads and delegates. It has read_file, glob, grep, web search, render_page and task, and bash, write_file and edit_file tell it to give the work to a worker.
  • chatd checks the brief and the report. A brief needs its Goal, Files, Constraints and Check lines and carries no code. A report that misses a field goes back to the worker once. Below each report chatd lists the files the task changed, the files the report left out, the checks that ran and the claims with no call behind them.
  • A Task card shows each worker: its status in words, call k of max, tokens, time, the brief, the report, chatd's check, its screenshots and its transcript. Stop, a queued message and Continue reach the worker.
  • The Context panel shows each running worker in its own section, with its context bar, its prefill bar and tok/s, or its decode rate, first token and acceptance. The Now dock has a row per worker.

Chat tab

  • A written file's text goes to the model as a stub from the next request on (path, lines, bytes, sha256), and a long read or command output stays whole until a compaction. The store keeps every text. One run on 2026-10-17 had grown from 25k to 162k tokens in 50 minutes.
  • A compaction cuts until the request lands under half the limit that set it off. The log gives the size before and after.
  • A memory refusal compacts the chat and the run goes on, instead of retrying the same prompt for 10 minutes and ending interrupted.
  • A run on a cloud model takes no run slot, so a DeepSeek chat no longer waits behind two chats on the engine.
  • Tool screenshots are append-only, so an earlier screenshot no longer changes the prompt. render_page says the check browser has WebGL2 and no WebGPU.
  • A failed finish_run no longer wedges a conversation (#41), and chatd's store releases its lock when a transaction cannot begin (#14).

Engine and caches

  • A worker's request (X-Tandem-Worker, X-Tandem-Parent-Session) is never a guest of another conversation. For 600 s after a worker's last request its parent's rows go to the NVMe rather than away, and a returning parent tries slot 0 first.
  • The park and the NVMe spill keep conversations they used to drop: a swap parks the longer conversation whole, a conversation the park refuses goes to the NVMe, and a restore parks the conversation it reads over.
  • A request with images resumes at the end anchor, as a text request already did (QWEN38_MM_END=off restores the old path).
  • The live row shows a prefill's rate from its first progress mark and while a layer-major window runs.
  • These restores copy rows the engine computed before and compute none. The tests hold every such resume's logits to a cold prefill's within 1e-4; the served text against 0.11.3 was not measured.

Proxy and setup

  • The proxy closes a socket whose TLS handshake failed, which leaked one fd per failed request (#38).
  • The Setup Guide's reset and an apply cannot run at once (#40).

Pull requests #14, #38, #40 and #41 are by NotMainstream.

Upgrade

Run the 0.11.4 installer again, then restart the engine and chatd. chatd's store moves to v8 in place at its first start. On a box you installed with --setup:

curl -fsSLO https://raw.githubusercontent.com/0xBakeer/TandemLLM/v0.11.4/install.sh
bash install.sh --setup --force-setup --yes
bash ~/TandemLLM/run/ops/use-profile.sh <your profile>
tandem chat restart

A box installed without --setup upgrades with bash install.sh --yes and the same --dir, then tandem restart and tandem chat restart.

TandemLLM 0.11.3

Choose a tag to compare

@0xBakeer 0xBakeer released this 17 Oct 08:30

TandemLLM 0.11.3 makes an install through the Setup Guide safe to retry: it checks the box before anything stops, repairs what it can, and says in plain words what broke. Super VL reads images, and the Chat tab measures a cloud model's turns and prices them. Requests on the raw path write the same text as in 0.11.2. Every change is in CHANGELOG.md, and the PDF below is the manual.

Setup Guide

  • tandem doctor checks an install and repairs what is safe: file modes, the run/ops copies, stale pid files, a hold left behind, the secrets file's mode. It reports what it does not change, such as a serve.env that does not load. It runs before every tandem start and in every Setup Guide install, and as tandem doctor [--check] [--json].
  • A new step checks the new setup before the restart: the scripts, serve.env with the new profile, the weights, the memory, the port, the interpreters. A failure ends the job there and nothing is stopped or changed.
  • TandemLLM's scripts call each other through bash, never through the execute bit. A start script that lost its execute bit no longer fails the restart.
  • A failed step says what broke, shows what tandem doctor repaired, and offers Retry from that step and Copy diagnostics.
  • A restart is one card with the job's step, the load's phases and the time left. A refresh or an offline page goes back to the job. A finished install has its own screen with Start chatting.
  • The status responder belongs to its tree: a responder of another checkout or an older release is replaced, and it carries the job and GET /v1/setup/status while the engine is away.
  • The weights step lists the weights on the box and removes a model's weights. It never removes the running profile or a folder another profile shares, and it writes the line that downloads them again.
  • tools/release_gate_setup.sh installs a candidate twice in scratch folders beside the live engine and runs the whole flow in a phone-sized browser, once with the execute bits stripped.

Chat tab and cloud models

  • Nemotron 3.5 Super VL reads images through its own vision tower: uploads and the screenshots of render_page.
  • A cloud model's turn has its tok/s, the first token's wait, its thinking tokens, the provider's cache hits and its cost. Performance and Usage keep the engine's requests apart from relayed ones, and Usage has a table of the engine against each backend.
  • The picker takes names, limits, image input and effort levels from the provider's model list. Images go only to a model that reads them, and a model id that appears later is stored disabled until it is turned on under Backends.
  • A run that builds or changes a web page checks it in a browser before it ends and closes with what was checked and what was not.
  • render_page reports the page's own console, failed loads and errors with the line of the chat's file. A run may make 100 model calls, and a chat sandbox has 4 GiB of memory.

Engine and conductor

  • A conversation's next turn goes to the side slot that holds the longest share of its prompt, so it no longer reads the conversation again on another slot.
  • A turn that ends inside a verified block commits through its end token, so NemotronH models keep their end anchor after tool calls.
  • The narrator is off by default, and the decider's memory claim is 3.0 GiB, so Laya fits beside Super VL.
  • Under the conductor a turn can get packages it did not get before (the class cores), and its text changes with them.

Upgrade

Run the 0.11.3 installer again, then restart the engine and chatd. The conductor's migrations run at the engine's first start, and the usage ledger moves to schema 10 in place. On a box you installed with --setup:

curl -fsSLO https://raw.githubusercontent.com/0xBakeer/TandemLLM/v0.11.3/install.sh
bash install.sh --setup --force-setup --yes
bash ~/TandemLLM/run/ops/use-profile.sh <your profile>
tandem chat restart

A box installed without --setup upgrades with bash install.sh --yes and the same --dir, then tandem restart and tandem chat restart.

TandemLLM 0.11.2

Choose a tag to compare

@0xBakeer 0xBakeer released this 16 Oct 22:13

TandemLLM 0.11.2 makes the Chat tab work on a fresh install. chatd, the Chat tab's server, now starts and stops with the engine, and the Chat tab says when chatd is down. Super VL gets its full 1,048,576-token window. Update every box that runs the Chat tab. Every model writes the same text as in 0.11.1. Every change is in CHANGELOG.md, and the PDF below is the manual.

chatd with the engine

On a plain or --setup install nothing started chatd, and the Chat tab fell back to an in-browser mock without saying so. Aron reported it in issue #3. Now tandem start, ops/start.sh, the systemd unit and the Setup Guide start chatd with the engine, and tandem stop stops it. An engine restart leaves it running, and the watchdog starts a chatd that died. tandem chat start|stop|restart|status|logs drive it, tandem status has a chatd line, and QSE_CHATD=off opts out.

The Chat tab names the problem when chatd is not running, with the command to run, instead of loading the mock. The mock now loads only for ?chat=mock.

Setup Guide and Super VL

The Setup Guide sets the number of chats and both windows with steppers. A model card's range is how far the model was measured, not a cap: above it the step says the count is untested, and the memory estimate decides, up to the engine's 16 chats. A window walks 8,192, 16,384 and on up to the model's own maximum, and the field takes any number, such as 128k or 1m.

Nemotron 3.5 Super VL takes a window up to 1,048,576 tokens, its checkpoint's own, for slot 0 and the side slots. I checked it to 249,983 prompt tokens, five needles of five found. A 1,000,000-token prompt is not measured yet.

Install fixes

  • bin/tandem loads its config on an install with no ops/active-profile. Before, tandem start and status ended with status 1 and no message on every plain and --setup install.
  • The installer copies roles.sh, watchdog.sh and hold.sh into run/ops. Every start printed roles.sh: No such file or directory.
  • ops/chatd.sh runs under the install's venv and reads the secrets file the engine reads. ops/make-secrets.sh writes that file, so the Setup Guide's generated admin password takes effect.
  • The Setup Guide's reset keeps an install's state/secrets.env.

Chat tab

  • Each chatd labels its sandbox containers and touches only its own. Before, a second chatd on the same Docker adopted the first one's containers and removed them.
  • A sandbox container removed or stopped outside chatd starts again at the next tool call. The same sandbox failure three calls in a row ends the run, and Continue goes on once the sandbox is back. The Continue card says why a run stopped.
  • The preview pane opens the running app. A port that starts listening opens in a Preview tab, a waiting pane names the command and offers Start, and present reports what the page loaded. render_page and the preview dial ::1 and 127.0.0.1 by address.
  • The model picker lists models, one row each. DeepSeek V4 Flash and V4 Pro through the proxy can be picked, and a DeepSeek run no longer fails on its output limit.
  • The Context panel shows a live run's figures and says why one is missing. The More menu opens downward. The Chat tab has no horizontal overflow from 320 to 1440 px.

Upgrade

Run the 0.11.2 installer again. It rewrites bin/tandem, run/ops/serve.env and the scripts in run/ops, and chatd then starts with the engine. A chatd started earlier keeps the old code until tandem chat restart. On a box you installed with --setup:

curl -fsSLO https://raw.githubusercontent.com/0xBakeer/TandemLLM/v0.11.2/install.sh
bash install.sh --setup --force-setup --yes
tandem chat restart

A box installed without --setup upgrades with bash install.sh --yes and the same --dir.

TandemLLM 0.11.1

Choose a tag to compare

@0xBakeer 0xBakeer released this 16 Oct 13:00

TandemLLM 0.11.1 is a security fix for the Chat tab. Update every box that runs it. The release also gives Bolt's EXL3 packs from 2.5 to 6.0 bits their StairCut price files, so drafting on them is no longer slower than plain decoding. Every model writes the same text as in 0.11.0. Every change is in CHANGELOG.md, and the PDF below is the manual.

Security

chatd, the Chat tab's server, reads and writes two folders that a chat's sandbox can change: the chat's workspace and the sandbox's home. In 0.10.0 and 0.11.0 chatd followed a symlink there. Code running in the sandbox could point an attachment upload, a file tool, a snapshot or the Open WebUI runner's files at a path outside the sandbox. chatd then read or wrote that path with the rights of the user it runs as.

In 0.11.1 no access in those folders follows a symlink. chatd opens every folder on the way with O_NOFOLLOW, writes a new file and renames it into place, and reads regular files only. A path with a symlink on it is refused. An attachment that cannot be saved under uploads/ still goes out with its message, and the prompt says why. Joey reported the upload case.

Upgrade

Run the 0.11.1 installer again, then restart chatd. chatd is its own process, so it keeps the old code until it restarts. On a box you installed with --setup:

curl -fsSLO https://raw.githubusercontent.com/0xBakeer/TandemLLM/v0.11.1/install.sh
bash install.sh --setup --force-setup --yes
bash ~/TandemLLM/src/ops/chatd.sh stop
bash ~/TandemLLM/src/ops/chatd.sh start

A box installed without --setup upgrades with bash install.sh --yes and the same --dir.

Bolt EXL3: drafting no longer loses to plain

In 0.11.0, Bolt's EXL3 packs at 3.0, 3.5 and 4.0 bits wrote prose and chat slower with LiLiCorr than with plain decoding: prose at 31 to 33 tok/s against about 41 plain. The packs from 2.5 to 6.0 had no StairCut price file. Without one, the cut kept a price of 1 ms for a one-row block, so it often threw away a draft it had already paid for. Each pack now ships its price file, measured on the Spark.

profile plain prose chat code
nemotron-bolt-exl3-2.0 (default) 43.2 65.6 71.1 102.1
nemotron-bolt-exl3-2.5 41.9 65.8 68.9 114.7
nemotron-bolt-exl3-3.0 41.6 58.1 69.3 100.8
nemotron-bolt-exl3-3.5 40.6 59.5 65.9 101.0
nemotron-bolt-exl3-4.0 40.4 52.0 62.0 97.9
nemotron-bolt-exl3-5.0 33.9 51.7 55.5 81.7
nemotron-bolt-exl3-6.0 29.1 40.1 50.1 76.3

One DGX Spark, 2026-10-16, tok/s. One request through the server, 512 greedy tokens, thinking off, the mean of 3 runs. The drafted columns use LiLiCorr and the lookup, and every drafted text equals the plain run's. These rows are now in the setup guide's speed table.

Also in 0.11.1

  • Two contributions by joeynyc. A pinned asset now downloads at its revision (pull request #1). NemotronH's saved-state fingerprint now covers its GGUF reader and the GGUF file (pull request #2). Because that fingerprint changed, Bolt's and Super VL's saved conversations from 0.10.0 and 0.11.0 are not reused, and their first request reads the prompt again.
  • Each weight card in the setup guide names its maker and its Hugging Face repository. turboderp's Flash-Next packs are listed as community packs.
  • The install is two commands, then the setup guide in the browser at http://127.0.0.1:8000/dashboard/#/setup.

Known limits

  • Super VL's EXL3 2.0 pack sometimes drafts prose below plain. In one of three runs on 0.11.1 it wrote prose at 33.5 tok/s against 36.5 plain; the other two ran at 37.3. The cause is not isolated yet.
  • The other limits of 0.11.0 still hold: see its release notes.

TandemLLM 0.11.0

Choose a tag to compare

@0xBakeer 0xBakeer released this 16 Oct 06:34

TandemLLM 0.11.0 adds a fifth model, NVIDIA's Nemotron 3.5 Super VL 120B-A12B. It runs from our EXL3 packs at 4.0 and 2.0 bits a weight or from NVIDIA's own NVFP4 release, and every profile drafts with NVIDIA's LiLiCorr drafter for Super VL. The Qwen, LFM2.5 and Bolt models write the same text at the same speed as in 0.10.0, and their saved chats carry over. Every change is in CHANGELOG.md, and the PDF below is the manual.

Nemotron 3.5 Super VL 120B-A12B

Super VL has Bolt's hybrid layout at a larger size: 40 Mamba2 layers, 40 mixture-of-experts layers and 8 attention layers, with 22 of 512 experts per token. The engine now reads NVIDIA's ModelOpt checkpoints as stored, so NVIDIA's NVFP4 release runs without a conversion: NVFP4 experts, FP8 Mamba2 and attention projections and an FP8 head.

profile download KL vs BF16 top-1 vs BF16 plain decode, tok/s
nemotron-super-vl-exl3-4.0 (default) 65.0 GB 0.049 92.9 % 31.1
nemotron-super-vl-exl3-2.0 36.84 GB 0.325 82.1 % 36.5
nemotron-super-vl-nvfp4 (NVIDIA's NVFP4) 75.06 GB 0.041 93.4 % 19.6

One DGX Spark, 2026-10-16. Quality: 8 wikitext-2 rows of 1,024 tokens against the logits of NVIDIA's BF16 checkpoint. Decode: one request through the server, 512 greedy tokens, the mean of 3 runs.

Use the 4.0 pack. Its KL is 0.008 above NVIDIA's NVFP4 release, and it decodes 1.6 times as fast. With LiLiCorr and the lookup it writes 53.6 tok/s on code, and edit and copy asks reach 101.0 and 108.3 tok/s. The 2.0 pack is 17 % faster plain, but its KL is more than six times the 4.0 pack's. Take it only when 4.0 does not fit.

Both packs are public repositories on Hugging Face, 0xBakeer/TandemLLM-Nemotron-3.5-Super-VL-120B-A12B-EXL3-<bpw>, pinned by commit, and both are in one collection. The NVFP4 release and the drafter come from NVIDIA's repositories. docs/nemotron-h.md has the comparison with vLLM on the same NVFP4 weights.

Upgrade

Run the 0.11.0 installer again, then switch to Super VL. On a box you installed with --setup:

curl -fsSLO https://raw.githubusercontent.com/0xBakeer/TandemLLM/v0.11.0/install.sh
bash install.sh --setup --force-setup --yes
~/TandemLLM/run/ops/use-profile.sh nemotron-super-vl-exl3-4.0 --dry-run   # each file's URL and size
~/TandemLLM/run/ops/use-profile.sh nemotron-super-vl-exl3-4.0

A box installed without --setup upgrades with bash install.sh --yes and the same --dir. A start of the 4.0 profile needs 90 GiB of free memory.

Known limits

  • Super VL is text only. Its vision tower is not served yet, and neither is its MTP head.
  • TandemLLM reads a prompt at 476 to 589 tok/s. vLLM reads the same prompts 4 to 5 times as fast.
  • With a drafter, requests at once take turns. Three at once run at 19.6 tok/s in total on the 4.0 pack.

TandemLLM 0.10.0

Choose a tag to compare

@0xBakeer 0xBakeer released this 16 Oct 00:47

TandemLLM 0.10.0 adds a fourth model, NVIDIA's Nemotron 3.5 Bolt 74B-A9B. It runs from our EXL3 packs at 2.0 to 6.0 bits a weight or from NVIDIA's own 2-bit GGUF, and the EXL3 profiles draft with NVIDIA's LiLiCorr drafter. The Qwen and LFM2.5 models write the same text at the same speed as in 0.9.2, and their saved chats carry over. Every change is in CHANGELOG.md, and the PDF below is the manual.

Nemotron 3.5 Bolt 74B-A9B

Bolt is a hybrid of 40 Mamba2 layers, 40 mixture-of-experts layers and 8 attention layers, with 9 of up to 496 experts per token. The engine runs a verify row with the same bits as the decode step, so a drafted answer is the plain answer. Where a reasoning budget forces a thinking block closed, the close can land a few tokens later (docs/exactness.md).

profile download KL vs BF16 top-1 vs BF16 plain decode, tok/s
nemotron-bolt-exl3-2.0 (default) 23.48 GB 0.170 84.1 % 43.3
nemotron-bolt-exl3-3.0 31.75 GB 0.061 89.7 % 41.7
nemotron-bolt-exl3-4.0 40.01 GB 0.034 92.7 % 40.5
nemotron-bolt-exl3-6.0 58.37 GB 0.0087 96.2 % 29.2
nemotron-bolt-iq2 (NVIDIA's GGUF) 22.04 GB 0.259 79.6 % 27.8

The 2.5, 3.5 and 5.0 packs have profiles too. One DGX Spark, 2026-10-15 and 16. Quality: 8 wikitext-2 rows of 1,024 tokens against the logits of NVIDIA's BF16 checkpoint. Decode: one request through the server, 512 greedy tokens, the mean of 3 runs.

The 2.0 pack keeps its routed experts at 2 bits and its dense projections at 4. It scores better and runs faster than NVIDIA's GGUF. With LiLiCorr and the lookup it writes 65.7 tok/s on prose and 102.8 on code. Edit and copy asks reach 180.5 and 244.7 tok/s (512 greedy tokens, thinking off, 3 runs). On the 4.0 pack LiLiCorr gives no speed in this release: StairCut keeps plain steps, and we have not found why. Three requests at once run at 72.1 tok/s in total.

Each pack is a public repository on Hugging Face, 0xBakeer/TandemLLM-Nemotron-3.5-Bolt-74B-A9B-EXL3-<bpw>, pinned by commit, and all seven are in one collection. The GGUF and the drafter come from NVIDIA's repositories. docs/nemotron-h.md has the checks against transformers, llama.cpp and BF16.

Chat tab

  • Each chat's sandbox has 1 GiB of memory, and a call that hits the limit fails with "out of memory".
  • Attachments are never inlined past the window. A file over a quarter of the free window goes in as one line with its path under /workspace/uploads/.
  • A tool call no longer waits without end for its sandbox. After 60 s it fails with the reason.

Upgrade

Run the 0.10.0 installer again, then switch to Bolt. On a box you installed with --setup:

curl -fsSLO https://raw.githubusercontent.com/0xBakeer/TandemLLM/v0.10.0/install.sh
bash install.sh --setup --force-setup --yes
~/TandemLLM/run/ops/use-profile.sh nemotron-bolt-exl3-2.0 --dry-run   # each file's URL and size
~/TandemLLM/run/ops/use-profile.sh nemotron-bolt-exl3-2.0

A box installed without --setup upgrades with bash install.sh --yes and the same --dir.

Known limits

  • Bolt is text only. Its image tower is not served yet.
  • The IQ2 profile runs without a CUDA kernel for its shared experts, so it decodes at 27.9 tok/s, not 32.7.
  • The IQ2 profile drafts with the lookup alone. With LiLiCorr beside it, StairCut kept plain steps on this build, and the cause is not known yet. Edit and copy asks still run at 97.9 and 131.2 tok/s.
  • The 2.5 to 6.0 packs have no StairCut price file yet. The cut learns their prices while it serves.

TandemLLM 0.9.2

Choose a tag to compare

@0xBakeer 0xBakeer released this 15 Oct 16:57

TandemLLM 0.9.2 fixes two install bugs that an early tester hit on a new DGX Spark with 0.9.1. The engine, the conductor and the dashboard do not change. Every change is in CHANGELOG.md, and the PDF below is the manual.

Fixes

  • Checksums: fetch_weights.py compared a download's file globs to file names as plain text. Qwen3.5-0.8B (the shadow reader) and Qwen3.5-2B (the narrator) list only globs, so their download checked no file and stopped with 0 files checked: FAILED. Laya's files under multilingual/ and typed-decisions/ were never checked. Now the globs pick the files to check.
  • EXL3 after install.sh --setup: the 27B's EXL3 profiles refused to switch, with base-plain already on disk. The installer wrote QWEN38_MODEL, an empty Hugging Face cache folder on a new box, after the weight profile, so the profile could not replace it. The installer's keys now come before the profile, and an EXL3 profile reads base-plain when that folder has no FP8 snapshot. A standalone community pack now reads its own folder on an installed box too.
  • HF_HOME: an install with HF_HOME or HF_HUB_CACHE set writes that cache to run/ops/serve.env. A later shell without the variable fetches the base into the same cache and finds it there.

Upgrade

Run the 0.9.2 installer again. It rewrites run/ops/serve.env and the scripts beside it; a git checkout of the tag keeps the old ones. On a box you installed with --setup:

curl -fsSLO https://raw.githubusercontent.com/0xBakeer/TandemLLM/v0.9.2/install.sh
bash install.sh --setup --force-setup --yes
~/TandemLLM/run/ops/use-profile.sh <profile>

A box installed without --setup upgrades with bash install.sh --yes and the same --dir. On a new DGX Spark:

curl -fsSLO https://raw.githubusercontent.com/0xBakeer/TandemLLM/v0.9.2/install.sh
bash install.sh --setup --yes
~/TandemLLM/run/ops/use-profile.sh exl3-4.5 --dry-run   # each file's URL and size
~/TandemLLM/run/ops/use-profile.sh exl3-4.5

Known limits

The limits of 0.9.1 still hold: see its release notes.

TandemLLM 0.9.1

Choose a tag to compare

@0xBakeer 0xBakeer released this 14 Oct 22:29

TandemLLM 0.9.1 adds web search and media playback to the Chat tab, and turns on the loop guard and memory notes in the shipped conductor profiles. The decode path does not change. Every change is in CHANGELOG.md, and the PDF below is the manual.

What's new

  • Web search in the Chat tab: a built-in web_search tool with DuckDuckGo (the default, no setup) or your own SearXNG instance, set in the chat settings. The model cites the URLs and reads a page with web_fetch.
  • Media in the Chat tab: video, audio and PDF files open in a player or the browser's PDF viewer, in the Files pane and the present card. chatd streams a workspace file with byte ranges, with no 2 MiB cap.
  • The loop guard is on in the shipped coding, chat-app, hermes, overnight and chat profiles. When the model makes the same tool call a third time in one user turn and the results were the same each time, the guard stops the call and the model writes a different one.
  • The loop escape: after a repeated or near-repeated call, the session samples with the model card's settings until it makes progress, then decodes greedy again. A client's own sampling wins. Output changes on those turns only.
  • Memory notes are on in the shipped chat, coding, hermes and chat-app profiles, so the Chat tab sees them too. The model is told the notes are its memory between chats. The Context panel shows a turn's notes.
  • --reasoning-effort none and off turn thinking off for every request that says nothing about thinking.

Fixes

  • Setup Guide: after a reload, a finished install job stays finished and keeps its whole log. The change list names the keys a model switch drops from run/setup.env.
  • Setup Guide: the fetch step downloads the models of the tools you turn on (the shadow reader, the narrator, Laya). A failed shadow reader load is tried again after 300 s.
  • The 27B's EXL3 profiles fetch only the base tensors an EXL3 load reads, by HTTP range requests: 3.54 GB instead of 30.41. A fresh exl3-6.0 downloads 36.48 GB, not 63.34.
  • Behind a reverse proxy, a 502, 503 or 504 during an engine restart shows the dashboard's cached page, which reloads once /health answers.

Upgrade

Stored conductor profiles migrate once at the first start. In the five profiles above, the loop guard turns on unless a stored version of the profile ever had it on, and a profile without a sampling section gets one with the loop escape on. A stored chat, coding, hermes or chat-app profile without a memory switch gets memory: on; an explicit value stays.

To upgrade a box you installed with --setup, check out 0.9.1 and switch to your profile again. Its files are on disk already, so nothing downloads twice:

curl -fsSLO https://raw.githubusercontent.com/0xBakeer/TandemLLM/v0.9.1/install.sh
bash install.sh --setup --force-setup --yes
~/TandemLLM/run/ops/use-profile.sh <profile>

A box installed without --setup upgrades with bash install.sh --yes and the same --dir. On a new DGX Spark:

curl -fsSLO https://raw.githubusercontent.com/0xBakeer/TandemLLM/v0.9.1/install.sh
bash install.sh --setup --yes
~/TandemLLM/run/ops/use-profile.sh lfm25-exl3-3.5 --dry-run   # each file's URL and size
~/TandemLLM/run/ops/use-profile.sh lfm25-exl3-3.5

Known limits

  • DuckDuckGo can answer with a rate limit or a bot check (HTTP 202). The tool returns that as an error result. SearXNG needs an instance with the json format on.
  • The loop guard catches a repeated call. A model that repeats a failing approach with different calls is not caught yet.
  • Carried over from 0.9.0: LFM2.5 has no draft head, and its shadow reader and KV pool are off. On LFM2.5 the conductor adds no memory notes. The Chat tab is in beta, there is no video input to the model, and the Flash-Next 5.05 pack does not load yet.

TandemLLM 0.9.0

Choose a tag to compare

@0xBakeer 0xBakeer released this 14 Oct 16:00

TandemLLM 0.9.0 adds a third model, Liquid AI's LFM2.5-24B-A2B, beside Qwen3.8-27B and Qwen3.8-Flash-Next. The Qwen models write the same text at the same speed as in 0.8.3. Every change is in CHANGELOG.md, and the PDF below is the manual.

What's new

  • LFM2.5-24B-A2B runs on the engine: 24B parameters, 4 of 64 experts a token, a 131,072-token context and three slots. The decode step, the verify block and the commit each run as one CUDA graph.
  • Seven LFM2.5 profiles: Liquid's BF16 checkpoint and six EXL3 packs from 2.5 to 6.0 bits a weight. The default is lfm25-exl3-3.5, the fastest in chat whose top token matches BF16's on at least 85 % of chat positions.
  • The lookup drafts with no draft head. Edit and copy asks run 1.8 to 3.6 times faster, and the text equals plain decoding.
  • The shared EXL3 kernels read half-integer rates (1.5, 2.5 and 3.5 bits a weight), as exllamav3 1.6.0 writes them below 4 bits. At whole rates they give the same bits as before.
  • The conductor, Laya and the narrator are on for LFM2.5, fitted to the model. On 2.5, four short asks used 2,234 reasoning tokens, against 2,155 with no conductor and 9,098 with the Qwen router as written.
  • Chat tab: the plus menu is no longer cut off, a page that a tool wrote opens from its tool card, and the Context panel counts every tool call, file, package, KV row and the resident prefix, or says why a figure is missing.
  • Fixes: /v1/completions with a text prompt and two or more slots no longer fails with 500, and a pack stored as one model.safetensors counts as complete.

LFM2.5-24B-A2B profiles

One DGX Spark, 2026-10-14. Chat: one greedy request through the server, 512 tokens, thinking off, plain decoding. Top-1: how often the top token matches BF16's, from exllamav3's model_diff on oasst1 chat.

profile download chat, tok/s chat top-1
lfm25-exl3-2.5 8.20 GB 185.4 78.9 %
lfm25-exl3-3.0 9.68 GB 171.3 83.6 %
lfm25-exl3-3.5 (default) 11.16 GB 150.9 86.7 %
lfm25-exl3-4.0 12.64 GB 143.7 88.5 %
lfm25-exl3-4.5 14.12 GB 128.2 91.2 %
lfm25-exl3-6.0 18.63 GB 105.2 93.4 %
lfm25-bf16 47.9 GB 44.5 100 %

The six packs are one Hugging Face collection: TandemLLM LFM2.5-24B-A2B EXL3. They are public, and a download needs no token.

Install

On a new DGX Spark:

curl -fsSLO https://raw.githubusercontent.com/0xBakeer/TandemLLM/v0.9.0/install.sh
bash install.sh --setup --yes
~/TandemLLM/run/ops/use-profile.sh lfm25-exl3-3.5 --dry-run   # each file's URL and size
~/TandemLLM/run/ops/use-profile.sh lfm25-exl3-3.5

To upgrade a box you installed with --setup, check out 0.9.0 and switch to your profile again. Its files are on disk already, so nothing downloads twice:

curl -fsSLO https://raw.githubusercontent.com/0xBakeer/TandemLLM/v0.9.0/install.sh
bash install.sh --setup --force-setup --yes
~/TandemLLM/run/ops/use-profile.sh <profile>

A box installed without --setup upgrades with bash install.sh --yes and the same --dir. Saved Qwen conversations carry over.

Known limits

  • LFM2.5 has no draft head yet. Liquid has not published its drafter, so the lookup drafts alone.
  • The shadow reader is off on LFM2.5, because it reads Qwen's token ids.
  • The KV pool is off on LFM2.5 and not verified there. Each slot reserves its window at load.
  • On LFM2.5 the conductor adds only the class's core skill. General packages, effort sentences and memory notes stay out until they can go somewhere other than the end of the user's message.
  • Laya stays below its 0.8 confidence bar on many short chats. Those turns run lean, at the profile's default level.
  • At the same bit rate the 24B packs lose more to BF16 (KL) than the 8B sibling does. The cause is not known.
  • Carried over from 0.8.3: the Chat tab is in beta, there is no video input, and the Flash-Next 5.05 pack does not load yet.

Credits

  • Liquid AI for LFM2.5-24B-A2B. The packs are quantizations of it and carry its license, the LFM Open License v1.0.
  • turboderp for exllamav3, which made the packs. Our EXL3 decode matches its LinearEXL3 bit for bit.