Request: wheel built against PyTorch 2.13 (current build caps users at SGLang <= 0.5.17)
The escha-1.2.1+qwen3dense wheel ships escha/_C.so prebuilt against PyTorch 2.9.x, and no kernel sources are included, so it cannot be rebuilt downstream. Since upstream SGLang 0.5.18 and 0.5.19 pin torch==2.13.0, this effectively caps users of the Escha runtime at SGLang 0.5.17 (torch 2.11).
I verified the exact incompatibilities on RTX 5070 (sm_120), Python 3.12:
torch 2.10 / 2.11 β works. Only one symbol is missing: c10::cuda::c10_cuda_check_implementation, whose line-number parameter changed int -> unsigned int. A 16 KB forwarding shim (LD_PRELOAD) resolves it, and kernel output is bit-identical to torch 2.9.1 across five argument combinations of escham_reconstruct on real Escha-W2 weights.
torch 2.13 β not recoverable from outside the binary:
- Five missing symbols (the above, plus
at::cuda::getCurrentCUDABlasHandlegaining abool setupparameter,materialize_cow_storage(StorageImpl&)->materialize_cow(StorageImpl*), and twotorch::Library::_defoverloads renamed byat::Tag->torch::headeronly::Tag). All shimmable. DispatchKeyrenumbering (Namedremoved):CUDAis 51 in 2.9/2.11 but 50 in 2.13, so the kernels register underHIP. Fixable by interposing thetorch::Libraryconstructor.TensorImpllayout change (blocking):PyObjectSlotshrank by 8 bytes, so every field after it moves βsizes_and_strides_64 -> 56,numel_160 -> 152,data_type_168 -> 160,device_opt_170 -> 162,key_set_176 -> 168,sizeof184 -> 176. The kernels read these fields through inlined accesses compiled at the old offsets, which surfaces asis_python_dispatch() INTERNAL ASSERT FAILEDand thenCUDA error: an illegal memory access was encountered. No external shim can fix this β it requires recompilation.
Would you consider publishing a second wheel built against torch 2.13 (cp312, manylinux_2_28)?
Alternatively, documenting the supported torch range explicitly in INSTALL.md would help β the current text says "2.9.x", but 2.10 and 2.11 also work with the one-symbol shim described above.
Follow-up on the same issue, with a concrete case for what the 0.5.17 cap costs on hybrid-SSM (GDN) deployments.
Two upstream changes landed after 0.5.17 that matter specifically for the W2 dense build on small cards:
- #15829 (
[feat] Support extra_buffer in Mamba2-based models) introduced--mamba-track-interval, decoupling where Mamba state checkpoints are taken fromchunked_prefill_size. - #34763 (
[Spec] Support mamba-radix-cache-strategy extra_buffer_lazy with DFLASH) added--mamba-radix-cache-strategy extra_buffer_lazy, which plans track slots lazily and now works with speculative decoding.
In the shipped tree, checkpoints are only produced at chunk boundaries, so the prefix-cache capacity condition is effectively
required mamba slots β kv_pool_tokens / chunked_prefill_size β€ max_mamba_cache_size
On 2Γ consumer 12 GB cards (sm_120), Qwen3.8-27B-Escha-W2, --kv-cache-dtype int2, 196,608-token context, --max-total-tokens 220000, --mamba-ssm-dtype float16, --mamba-scheduler-strategy extra_buffer, this is what the trade-off measures:
CHUNK |
required slots | prefix cache | TTFT while another stream is prefilling | cold 192K prefill |
|---|---|---|---|---|
| 4096 | ~73 (> max_mamba_cache_size=40) |
collapses (#cached-token: 0 on every request, no error surfaced) |
1.73 s | 111 s |
| 6144 | ~36 | works (192K resend: 212.5 s β 1.7 s) | 11.17 s | 457 s |
So on this class of hardware the only way to keep the prefix cache alive is to raise chunked_prefill_size, and that costs 6.5Γ on TTFT under concurrency and 4Γ on long-prefill wall time. With --mamba-track-interval the two knobs are independent, which removes the trade-off entirely rather than trading one regression for another.
As an interim workaround we backported upstream's --enable-int8-mamba-checkpoint into the installed tree (int8 checkpoint slots, ~2Γ capacity at the same VRAM) so the capacity condition can be met at CHUNK=4096. It works around the symptom, but the track-interval change is the actual fix, and it only ships in β₯ 0.5.18 β which needs torch 2.13, hence this request.
Two questions:
- Is a wheel built against torch 2.13 (or a rebase onto SGLang β₯ 0.5.18) on the roadmap, even roughly?
- In the MoE repo (discussion #8) there was a note about open-sourcing the whole runtime stack. If that includes the SGLang fork, downstream users could rebase onto current upstream themselves and stop waiting on wheel rebuilds β is that still the plan?
Happy to test any preview build on sm_120 and report back with the same measurements.
Thanks for both reports. Pushed 1.2.2. See the updated README/INSTALL.md for the torch-version table and what changed.
torch 2.13: not built or tested yet (our box tops out at CUDA 12.8, 2.13 wants 12.9/13.0). The stable-ABI design should extend there. It never touches TensorImpl fields or hardcodes DispatchKey ordinals, so none of your three break points apply. But that's unverified.
mamba-track-interval: It is already in the bundled fork (an undocumented oversight on our end) and decouples checkpoint spacing from chunked_prefill_size under --mamba-scheduler-strategy extra_buffer, which your command already sets. Pass it straight to serve.sh; curious whether it removes the trade-off on your 2Γ12GB setup.
Open-sourcing the fork: still the plan, no date yet. We will try to release the full runtime stack before November, and it will be opensourced together with our next major release. Stay tuned!
Thank you β 1.2.2 stable ABI is exactly what was needed.
Turnaround on this was remarkably fast, and the stable-ABI approach solves the problem at the root rather than per-torch wheels. Much appreciated.
One offer: your 1.2.2 verification was on an RTX 4090 (sm_89). I'm running Qwen3.8-27B-Escha-W2 on 2x RTX 5070 12GB (sm_120, consumer Blackwell) with TP2 + OSCAR int2 KV, which is a tighter memory regime than most setups β mamba state is 75.5 MB/request (48 linear-attention layers x 48 value heads x 128 x 128, fp16), so the mamba pool takes ~4x the space of the int2 KV pool.
I'll test 1.2.2 with torch 2.13 + sglang 0.5.18 on sm_120 and report back: import, byte-identical greedy output vs 1.2.1, and decode throughput. If sglang-kernel from the CUDA-12 index behaves differently on sm_120 than sm_100, that seems worth documenting in INSTALL.md.
Re: --mamba-track-interval already working under --mamba-scheduler-strategy extra_buffer β thank you for the correction, I had assumed it needed 0.5.18. I'll measure it on the current build.
Looking forward to the runtime OSS release.
Report: 1.2.2 runs on torch 2.13 / sm_120 β thank you
The stable-ABI build works. I have been running it on torch 2.13.0+cu129 with stock upstream sglang 0.5.19 (RTX 5070 12GB x2, sm_120, WSL2, TP2) for a full day now, and it is serving production traffic as of today.
To be precise about what this unlocked: the stable ABI did not make anything faster by itself β it made the engine choosable. Before 1.2.2 we were pinned to torch 2.9 and therefore to sglang <= 0.5.17. Now the same 2-bit weights run on 0.5.19, which is where the newer mamba/radix features live.
Measured on Qwen3.8-27B-Escha-W2 with OSCAR INT2 KV, 12GB x2:
| context | 114,688 |
| KV pool | 148,058 tokens |
| concurrency | 8 (aggregate 210 tok/s, worst TTFT 0.48 s) |
| decode (bs1) | 52.4 tok/s |
| prefill | 112K in 116 s (907 tok/s) |
| prefix reuse | 0.21 s |
| free VRAM at peak | 1.0 GB |
Quality is unchanged from our 0.5.15 deployment: 19/20 on a discriminative long-context test (two-field extraction among near-identical distractors, multi-position aggregation, ordered enumeration).
One small thing: the model card still says pip install 'torch==2.9.*' is "a hard pin, not a suggestion". That is no longer true for 1.2.2 β it may be worth updating, since the 2.9 pin is exactly what stops people from reaching 0.5.19.
Full configuration, patches and numbers, in case they are useful to other 12GB users: https://github.com/Nakanokensetsu/sglang -> escha_oscar_0519/
Thanks again for turning this around so quickly.