Repository navigation
Open
Description
Commit or version
v2.1.0
Environment
- colibri: v2.1.0 (Windows runtime,
START-HERE.batdefault launch) - OS: Windows [version]
- Python: 3.13
- CPU / RAM: 9800x3d, 32gb DDR5 memory
- GPU: AMD Radeon RX 9060 XT, AMD proprietary driver 26.10.44 (LLPC)
- Model: Qwen3.6-35B-A3B, int4 packed (
qwen36-35b) - Relevant banner lines (default launch):
cache=223/layer bits=4 ctx=65536[VK] cooperative matrix off on AMD's own driver ...(COLI_VK_COOPwas never set in any run below)[VK] tier qwen36: on, budget 11.84 GiB = 7089 experts[VK] tier qwen36: host pool on, 3151 experts in 5.25 GiB of system RAM[VK] tier qwen36: warm start, 10240 experts ... every expert of the model
Reproduction steps
Title
qwen36 on Vulkan (RX 9060 XT): output degrades into repetition after ~3 requests when all experts are resident; healthy on CPU, with the host pool off, or with the host pool capped below full residency
Summary
With the default launch of Qwen3.6-35B-A3B (int4) on an AMD discrete GPU, generations are fine for the first 2-3 requests and then collapse into repetitive text. Each request is an independent single-message conversation, so this is not conversation growth. The collapse appears to depend on the whole expert set being resident (device VRAM plus host pool). Capping the host pool just below that point gives healthy output.
Expected behavior
Test script:
$base = "http://127.0.0.1:8000/v1"
$model = (Invoke-RestMethod "$base/models").data[0].id
$topics = "a lighthouse keeper","a deep-sea diver","a train conductor","a beekeeper","a night watchman","a ferry captain","a clockmaker","a mountain guide"
$i = 0
foreach ($t in $topics) {
$i++
$body = @{ model=$model; messages=@(@{role="user";content="Write a detailed 300 word story about $t."}); max_tokens=400; temperature=0.7 } | ConvertTo-Json -Depth 5
$sw = [Diagnostics.Stopwatch]::StartNew()
$r = Invoke-RestMethod "$base/chat/completions" -Method Post -ContentType "application/json" -Body $body
$sw.Stop()
$w = ($r.choices[0].message.content -split '\s+') | Where-Object { $_ }
"{0}: ratio {1:N2} | {2} tokens | {3:N1} t/s" -f $i, (($w | Sort-Object -Unique).Count / [math]::Max($w.Count,1)), $r.usage.completion_tokens, ($r.usage.completion_tokens / $sw.Elapsed.TotalSeconds)
}Expected
Unique-word ratio stays around 0.6-0.7 for every request.
Actual behavior and logs
## Actual (default launch, cold start)
1: 0.68 | 50.7 t/s 5: 0.11 | 72.7 t/s
2: 0.66 | 51.6 t/s 6: 0.32 | 48.5 t/s
3: 0.60 | 51.1 t/s 7: 0.17 | 65.0 t/s
4: 0.16 | 74.5 t/s 8: 0.18 | 60.7 t/s
Other cold starts with the same prompt showed the same pattern (healthy for requests 1-3, collapsed from request 4 or 5 onwards). One run was already degraded from request 1, so the onset is not perfectly deterministic.
Collapsed replies repeat a word or phrase until the token limit (e.g. "a beacon, a beacon, ..."). Throughput rises to 60-80 t/s during collapse. Lookup drafting accepts almost everything then (`acceptance 98.2%`), versus 0% on healthy prose, so those speeds are loops, not real speedups.
## Steps to reproduce
1. Start the server with the stock `START-HERE.bat` (also reproduces with `coli web --host 0.0.0.0` plus `COLI_VULKAN=1`).
2. Wait for `OpenAI-compatible API listening`.
3. Send 8 independent chat requests (`temperature` 0.7, `max_tokens` 400), each a fresh single-message conversation, e.g. "Write a detailed 300 word story about {topic}." with a different topic each time.
4. Score each reply by unique-word ratio (unique words / total words). Healthy prose scores about 0.6-0.7. Looping text falls below 0.2.
## What changes the behavior
| Configuration | Result (8 requests) |
|---|---|
| Default launch | Collapses around request 4 |
| CPU only (`--gpu none`, `COLI_VULKAN` unset) | Healthy but slow - ~14t/s |
| `COLI_VK_TIER_HOST=0` (host pool off) | Healthy,~40 t/s (two runs) |
| `COLI_VK_TIER_HOST_GB=1` or `2` | Healthy, about 40 t/s |
| `COLI_VK_TIER_HOST_GB=5` | Healthy, about 44-45 t/s |
| `COLI_VK_HOST_POOL_IMPORT=0` | Still collapses |
| `COLI_VK_HYBRID_GATE=0` | Worse (degraded from request 1) |
| `COLI_LOOKUP=0` | Still collapses (not confirmed that `0` disables lookup) |
| Tuning profile removed | Still collapses |
| `.coli_usage` renamed (empty expert history) | Degraded from request 1 |
## Observation and hypothesis
Default launch (broken): the warm start places every expert (`10240`), with `CPU RAM hits 0, disk loads 0, evictions 0`.
`COLI_VK_TIER_HOST_GB=5` (healthy): `10109` of 10240 experts resident, with `disk loads 3`. The in-frame hybrid path is still active in this run (`4776 layer steps with the routed experts in the frame`).
Hypothesis (not confirmed): the fault only appears when the entire expert set is resident, so the engine never exercises its path for non-resident experts. An empty usage history also breaks it, which suggests expert placement affects it. I haven't looked at the engine source, so the underlying cause is unknown.
## Workaround
`COLI_VULKAN=1` plus `COLI_VK_TIER_HOST_GB=5` gives healthy output at about 44-45 t/s. Capping the host pool below full residency is enough.
## Additional notes
- `coli tune` reports "baseline retained" and is not involved.
- Cooperative matrix is off by default per the banner and was never enabled in these runs.
- I can probably fish up some Server log excerpts from healthy and broken runs on request.Metadata
Metadata
Assignees
Labels
No labels
Activity
JustVugg commentedon Nov 4, 2026
On it
JustVugg commentedon Nov 4, 2026
Thanks for the detailed report, the configuration table pointed straight at it. With experts in the host pool, the Vulkan chain computes the pool's experts on the CPU inside its frame and meets the device on Vulkan events. Two of those barriers were wrong: the step's sum read the device experts' output with no barrier after the dispatch that wrote it, and the event's stage mask held a stage Vulkan does not allow there. An NVIDIA card and Lavapipe serialize around events and hide it, a Radeon need not. #2588 fixes both: the Khronos validation layer's synchronization check found them at every hybrid step on dev and finds none with the fix.
If you can build the branch
fix/vk-hybrid-event-barriers, your 8-request script with the default launch (noCOLI_VK_TIER_HOST_GB), and once withCOLI_VK_HYBRID_GATE=0, would confirm it on your card. Otherwise it will be in the next release. If it still collapses, the[VK] qwen36 chain:and[VK] tier qwen36lines from a broken run's server log would help.lloyd-livengood commentedon Nov 4, 2026
No $env:COLI_VK_TIER_HOST_GB and no $env:COLI_VK_HYBRID_GATE=0:
1: ratio 0.06 | 400 tokens | 91.4 t/s
2: ratio 0.08 | 400 tokens | 80.9 t/s
3: ratio 0.08 | 400 tokens | 88.5 t/s
4: ratio 0.24 | 400 tokens | 75.1 t/s
5: ratio 0.20 | 400 tokens | 73.2 t/s
6: ratio 0.27 | 400 tokens | 57.3 t/s
7: ratio 0.19 | 400 tokens | 66.5 t/s
8: ratio 0.07 | 400 tokens | 84.3 t/s
1: ratio 0.20 | 400 tokens | 70.3 t/s
2: ratio 0.18 | 400 tokens | 72.4 t/s
3: ratio 0.12 | 400 tokens | 71.3 t/s
4: ratio 0.14 | 400 tokens | 79.5 t/s
5: ratio 0.36 | 400 tokens | 55.6 t/s
6: ratio 0.65 | 400 tokens | 57.3 t/s
7: ratio 0.63 | 400 tokens | 57.4 t/s
8: ratio 0.15 | 400 tokens | 80.6 t/s
No $env:COLI_VK_TIER_HOST_GB with $env:COLI_VK_HYBRID_GATE=0:
1: ratio 0.14 | 400 tokens | 82.5 t/s
2: ratio 0.06 | 400 tokens | 89.9 t/s
3: ratio 0.06 | 400 tokens | 78.0 t/s
4: ratio 0.15 | 400 tokens | 73.9 t/s
5: ratio 0.13 | 400 tokens | 70.3 t/s
6: ratio 0.14 | 400 tokens | 76.3 t/s
7: ratio 0.20 | 400 tokens | 61.6 t/s
8: ratio 0.07 | 400 tokens | 83.4 t/s
1: ratio 0.29 | 400 tokens | 57.0 t/s
2: ratio 0.08 | 400 tokens | 70.0 t/s
3: ratio 0.10 | 400 tokens | 78.0 t/s
4: ratio 0.06 | 400 tokens | 84.9 t/s
5: ratio 0.17 | 400 tokens | 72.0 t/s
6: ratio 0.11 | 400 tokens | 83.2 t/s
7: ratio 0.32 | 400 tokens | 64.4 t/s
8: ratio 0.03 | 400 tokens | 86.9 t/s
Server log for those last 16 fails:
t1.txt
out of curiosity I wanted to see if something in my config was tripping up, and the results weren't promising.
START-HERE.bat test after switch to branch:
1: ratio 0.09 | 400 tokens | 77.0 t/s
2: ratio 0.09 | 400 tokens | 74.9 t/s
3: ratio 0.06 | 400 tokens | 82.5 t/s
4: ratio 0.06 | 400 tokens | 81.4 t/s
5: ratio 0.09 | 400 tokens | 80.4 t/s
6: ratio 0.05 | 400 tokens | 83.3 t/s
7: ratio 0.06 | 400 tokens | 82.5 t/s
8: ratio 0.04 | 400 tokens | 84.0 t/s
START-HERE.bat after full clean installation and switch to branch:
1: ratio 0.18 | 400 tokens | 70.9 t/s
2: ratio 0.08 | 400 tokens | 81.9 t/s
3: ratio 0.06 | 400 tokens | 81.8 t/s
4: ratio 0.09 | 363 tokens | 81.3 t/s
5: ratio 0.15 | 400 tokens | 66.2 t/s
6: ratio 0.08 | 400 tokens | 81.7 t/s
7: ratio 0.08 | 400 tokens | 79.8 t/s
8: ratio 0.12 | 400 tokens | 73.6 t/s
t2.txt
lloyd-livengood commentedon Nov 4, 2026
Sorry for wall of text. I also ran with my own config with these again:
1: ratio 0.59 | 400 tokens | 50.1 t/s
2: ratio 0.63 | 400 tokens | 50.5 t/s
3: ratio 0.66 | 400 tokens | 50.6 t/s
4: ratio 0.61 | 400 tokens | 50.4 t/s
5: ratio 0.66 | 400 tokens | 50.1 t/s
6: ratio 0.64 | 400 tokens | 50.5 t/s
7: ratio 0.59 | 400 tokens | 50.4 t/s
8: ratio 0.58 | 400 tokens | 49.8 t/s
1: ratio 0.63 | 400 tokens | 51.0 t/s
2: ratio 0.62 | 400 tokens | 50.5 t/s
3: ratio 0.66 | 400 tokens | 50.1 t/s
4: ratio 0.65 | 400 tokens | 50.1 t/s
5: ratio 0.63 | 400 tokens | 49.7 t/s
6: ratio 0.68 | 400 tokens | 50.3 t/s
7: ratio 0.61 | 400 tokens | 49.9 t/s
8: ratio 0.67 | 400 tokens | 50.6 t/s
test.txt
vulkan chain: the hybrid steps leave the events where a frame does no…
JustVugg commentedon Nov 4, 2026
Thanks for testing, and sorry the first fix missed it. Your logs and one more experiment point at the cause. In a hybrid step the frame waits on an event that the host sets while the frame is already running. The current Vulkan spec asks for such an event to be set before the frame is submitted (VUID-vkSetEvent-event-09543), so a driver is allowed to let the frame through, and the step then reads the CPU's expert rows before they are written. On our RTX PRO 4000, making the frame skip that wait reproduces your symptoms with every expert resident: "1 1 1 1", broken words, speeds only a loop reaches. It also fits your table: the more host pool work per step (full residency, an empty usage history,
COLI_VK_HYBRID_GATE=0), the more often the CPU loses that race; with 5 GB its part is short enough to finish first.Two things would confirm it on your card:
COLI_VK_HYBRID_EVENTS=0, which runs the same steps on timeline semaphores, the form the spec allows.fix/vk-hybrid-event-barriersagain, now updated (vulkan chain: the hybrid steps leave the events where a frame does not wait for the host's, and their barriers #2588). At start the chain checks whether the frame really waits. If it does not, it prints[VK] chain: this driver does not hold a frame at an event the host sets while it runsand uses the timelines by itself, so your default launch should give healthy ratios. Whether that line shows up in the server log tells us what the probe saw.lloyd-livengood commentedon Nov 4, 2026
With launch params $env:COLI_VULKAN = "1"
$env:COLI_VK_COOP = "1"
$env:COLI_VK_HYBRID_EVENTS="0" 1: ratio 0.63 | 400 tokens | 56.5 t/s
2: ratio 0.63 | 400 tokens | 57.9 t/s
3: ratio 0.63 | 400 tokens | 57.2 t/s
4: ratio 0.64 | 400 tokens | 57.6 t/s
5: ratio 0.62 | 400 tokens | 57.1 t/s
6: ratio 0.67 | 400 tokens | 57.6 t/s
7: ratio 0.63 | 400 tokens | 57.7 t/s
8: ratio 0.66 | 400 tokens | 57.5 t/s
t3.txt
After git pull and launch from START-HERE.bat 1: ratio 0.17 | 400 tokens | 72.4 t/s
2: ratio 0.10 | 400 tokens | 79.7 t/s
3: ratio 0.05 | 400 tokens | 79.8 t/s
4: ratio 0.08 | 400 tokens | 71.4 t/s
5: ratio 0.05 | 400 tokens | 83.5 t/s
6: ratio 0.11 | 400 tokens | 70.1 t/s
7: ratio 0.07 | 400 tokens | 80.4 t/s
8: ratio 0.15 | 400 tokens | 78.8 t/s
t4.txt
After git pull and launch with params $env:COLI_VULKAN = "1"
$env:COLI_VK_COOP = "1"
$env:COLI_VK_HYBRID_EVENTS="0"
1: ratio 0.66 | 400 tokens | 56.3 t/s
2: ratio 0.61 | 400 tokens | 57.3 t/s
3: ratio 0.63 | 400 tokens | 57.2 t/s
4: ratio 0.64 | 400 tokens | 57.3 t/s
5: ratio 0.62 | 400 tokens | 57.1 t/s
6: ratio 0.65 | 400 tokens | 57.4 t/s
7: ratio 0.62 | 400 tokens | 57.8 t/s
8: ratio 0.66 | 400 tokens | 57.5 t/s
t5.txt
PS C:\Users\me\colibri> git status
On branch fix/vk-hybrid-event-barriers
Your branch is up to date with 'origin/fix/vk-hybrid-event-barriers'.
That Hybrid events solves things and nets a huge amount of speed, but issue persists in START-HERE.bat default configuration.
Oh, and all tests run with that same script with temp 0 and max_tokens 400.
lloyd-livengood commentedon Nov 4, 2026
Out of an abundance of caution, here is my hacky PowerShell script I use to launch/debug it with custom params. I set it up initially to communicate to my Mac mini by ethernet, that's what the allowed host set is for. In case it's user error and I am a dummy.
Start Colibri server and web dashboard
$ErrorActionPreference = "Stop"
Run from the installation folder
Set-Location $PSScriptRoot
Ask for the API key without displaying it
$secureKey = Read-Host "Enter your NEW Colibri API key" -AsSecureString
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureKey)
try {
$env:COLI_API_KEY = [Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr)
$env:COLI_VULKAN = "1"
$env:COLI_VK_COOP = "1"
$env:COLI_VK_HYBRID_EVENTS="0"
}
finally {
Remove-Item Env:\COLI_API_KEY -ErrorAction SilentlyContinue
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
Write-Host "`nColibri process ended."
}