Yi-VL Model - #112
Yi-VL Model#112
Conversation
|
@BabyChouSr I ran python test_openai_server.py --test-image, |
merrymercy
left a comment
There was a problem hiding this comment.
Looks good to me!
- Could you also convert the 34B version?
- Could you upload the conversion script?
- Could you add an example similar to this one https://github.com/sgl-project/sglang/blob/main/examples/quick_start/srt_example_llava.py, but for Yi-VL?
|
try an example in srt_example_llava.py state = image_qa.run( image_path="images/cat.jpeg", question="What is this?", max_new_tokens=64) then |
|
I don't know the placeholder for Yi models. it can be different but the key part is the respective token being missing most probably since the error is caused by |
I believe that the sglang frontend language (using the example from |
If so, why does "64002 is not in list" happen? |
Are you using the following for your runtime? |
I used the runtime of endpoint. It failed with same error using cli above. |
|
@paulcx I posted some new changes, try running: |
will try later. btw i found yi-vl architecture and model class were not found in model runner by hf config only. so i changed with hard code for now. |
It works. Also works with: |
merrymercy
left a comment
There was a problem hiding this comment.
@BabyChouSr Ready to be merged?
Yup! |
|
It looks like this PR has been merged to SGLang v0.1.11. |
|
What is your model_path and tokenizer_path? One reason I can think of is that the 34B LLava uses Yi-Chat as the language model so the image token index is 64002, but vicuna-based language models will have image token index of 32000, thus causing the mismatch. |
|
@loveunk llava-1.6-34B is not the same as the Yi-VL in this PR, although they used the same base model Yi-34B. If you use sglang/python/sglang/lang/chat_template.py Lines 171 to 172 in ee1df26 For now, you can follow https://github.com/haotian-liu/LLaVA?tab=readme-ov-file#Demo to use llava 34B with SGLang. They handled chat template correctly in their interface. |
|
sglang=0.1.12 vllm=0.3.0
|
* set default strides for outputs * checkpoint * Support input/output stride specification in search * undo changes in cmake files * fix json key error
* kimi25 docs * kimi25 docs
…n-TP expert sharding fused_moe_gguf's MMQ path (prefill / M>64) passes expert_ids from moe_align_block_size straight to the sgl-kernel ggml_moe_a8. That buffer is torch.empty-allocated and the align kernel only fills blocks up to num_tokens_post_padded — the TRAILING block entries are UNINITIALIZED garbage. The MMQ device kernel (sgl-kernel moe.cuh moe_q) guards expert ids with a HARDCODED `exp_idx > 255 || exp_idx < 0`. That is exact for a full 256-row expert table (garbage >= 256 is rejected), but under uneven-TP EXPERT-DIM sharding (sgl-project#80/sgl-project#81) each rank's LOCAL weight table has only n_local+1 rows (owned experts + the trailing zero-pad expert). Garbage ids in [E_local, 255] pass the 256 guard, and the kernel reads `vx + exp_idx * exp_stride` beyond the local weight tensor -> illegal memory access. Observed live (task sgl-project#82 emulation): Qwen3.6-35B-A3B UD-Q4_K_XL GGUF, TP=3 --rank-gpu-id 0,1,2 --rank-tp-ratio auto (expert-dim sharding, rank owns ~114 of 256 experts), crashes on the FIRST prefill > 64 tokens: RuntimeError: Triton Error [CUDA]: an illegal memory access Diagnosis was initially misattributed to the GDN/cumsum kernel (the async IMA surfaced at the next kernel launch); CUDA_LAUNCH_BLOCKING=1 relocated the true fault to fused_moe_gguf -> ggml_moe_a8 -> activation.cuh. The MMVQ decode path (M<=64) takes no expert_ids blocks and was unaffected, which is why decode/short prompts looked fine. Fix: sanitize out-of-range block ids to -1 before ggml_moe_a8 — `expert_ids = expert_ids.masked_fill(expert_ids >= E, -1)` — so the kernel's own `exp_idx < 0` guard rejects trailing garbage. Every VALID block id is < E by construction, so only garbage/trailing blocks are touched; the result is byte-identical for the full-table (E=256, TP=1) path. masked_fill with a SCALAR is a device-only op with no host->device copy, so it is CUDA-graph-capture safe (a torch.where against a freshly constructed host scalar tensor is NOT — it aborts MTP/NEXTN graph capture with "Cannot copy between CPU and CUDA tensors during CUDA graph capture"). Python-side deliberately: sgl_kernel ships prebuilt, and this mirrors the existing _ggml_moe_get_block_size fallback (usable without a kernel rebuild). The durable kernel-side bound (exp_idx < nrows(W_local) instead of the hardcoded 255) is filed as backlog sgl-project#112. Pre-existing bug (moe.cuh, gguf.py, moe_align_block_size — none touched by task sgl-project#82; reproduced on the plain uneven-TP GGUF MoE path). Also a latent OOB for ANY GGUF MoE with < 256 experts even without sharding. Test results: - NEW test/registered/unit/quantization/test_gguf_moe_expert_ids_sanitize.py: 5/5 pass (sharded-garbage sanitized to -1; full-table E=256 byte-identical no-op; boundary id == E excluded; dtype/shape preserved). - LIVE (eager): Qwen3.6-35B-A3B GGUF TP=3 uneven, previously crashed on first prefill>64: now boots and generates coherently — temp-0 battery correct (17*23=391, next-after-16=32, Paris, Shakespeare, German translation), and the 15k-token needle prefill (the exact MMQ path that crashed) completes without IMA. - Graph-safety: full-perf boot (CUDA graphs + NEXTN) passes MoE + target- verify graph capture with masked_fill (the torch.where/new_tensor form aborted capture; that is why masked_fill is used). - py_compile clean.
…n-TP expert sharding fused_moe_gguf's MMQ path (prefill / M>64) passes expert_ids from moe_align_block_size straight to the sgl-kernel ggml_moe_a8. That buffer is torch.empty-allocated and the align kernel only fills blocks up to num_tokens_post_padded — the TRAILING block entries are UNINITIALIZED garbage. The MMQ device kernel (sgl-kernel moe.cuh moe_q) guards expert ids with a HARDCODED `exp_idx > 255 || exp_idx < 0`. That is exact for a full 256-row expert table (garbage >= 256 is rejected), but under uneven-TP EXPERT-DIM sharding (sgl-project#80/sgl-project#81) each rank's LOCAL weight table has only n_local+1 rows (owned experts + the trailing zero-pad expert). Garbage ids in [E_local, 255] pass the 256 guard, and the kernel reads `vx + exp_idx * exp_stride` beyond the local weight tensor -> illegal memory access. Observed live (task sgl-project#82 emulation): Qwen3.6-35B-A3B UD-Q4_K_XL GGUF, TP=3 --rank-gpu-id 0,1,2 --rank-tp-ratio auto (expert-dim sharding, rank owns ~114 of 256 experts), crashes on the FIRST prefill > 64 tokens: RuntimeError: Triton Error [CUDA]: an illegal memory access Diagnosis was initially misattributed to the GDN/cumsum kernel (the async IMA surfaced at the next kernel launch); CUDA_LAUNCH_BLOCKING=1 relocated the true fault to fused_moe_gguf -> ggml_moe_a8 -> activation.cuh. The MMVQ decode path (M<=64) takes no expert_ids blocks and was unaffected, which is why decode/short prompts looked fine. Fix: sanitize out-of-range block ids to -1 before ggml_moe_a8 — `expert_ids = expert_ids.masked_fill(expert_ids >= E, -1)` — so the kernel's own `exp_idx < 0` guard rejects trailing garbage. Every VALID block id is < E by construction, so only garbage/trailing blocks are touched; the result is byte-identical for the full-table (E=256, TP=1) path. masked_fill with a SCALAR is a device-only op with no host->device copy, so it is CUDA-graph-capture safe (a torch.where against a freshly constructed host scalar tensor is NOT — it aborts MTP/NEXTN graph capture with "Cannot copy between CPU and CUDA tensors during CUDA graph capture"). Python-side deliberately: sgl_kernel ships prebuilt, and this mirrors the existing _ggml_moe_get_block_size fallback (usable without a kernel rebuild). The durable kernel-side bound (exp_idx < nrows(W_local) instead of the hardcoded 255) is filed as backlog sgl-project#112. Pre-existing bug (moe.cuh, gguf.py, moe_align_block_size — none touched by task sgl-project#82; reproduced on the plain uneven-TP GGUF MoE path). Also a latent OOB for ANY GGUF MoE with < 256 experts even without sharding. Test results: - NEW test/registered/unit/quantization/test_gguf_moe_expert_ids_sanitize.py: 5/5 pass (sharded-garbage sanitized to -1; full-table E=256 byte-identical no-op; boundary id == E excluded; dtype/shape preserved). - LIVE (eager): Qwen3.6-35B-A3B GGUF TP=3 uneven, previously crashed on first prefill>64: now boots and generates coherently — temp-0 battery correct (17*23=391, next-after-16=32, Paris, Shakespeare, German translation), and the 15k-token needle prefill (the exact MMQ path that crashed) completes without IMA. - Graph-safety: full-perf boot (CUDA graphs + NEXTN) passes MoE + target- verify graph capture with masked_fill (the torch.where/new_tensor form aborted capture; that is why masked_fill is used). - py_compile clean.
…in) as pure composition — local expert count (global would index past weights), -1 slots to expert 0 at zero weight (sgl-project#112 bound, exact), routed_scaling deliberately not forwarded (ep_gather has no post-permute apply — forwarding would double-scale silently); latent gating_output crash found by reading the callee's AST, invisible to hermetic tests (sgl-project#374 desk)
…pert stride; catch-all probe registration Three sgl-kernel csrc fixes, each with an off-GPU can-discriminate test (pure tree change -- wheel NOT built/installed here): - sgl-project#511 (audit sgl-project#506 axis 4, sgl-project#380 class): the GGUF MXFP4 numeric gate was loose enough that an all-zeros or sign-flipped output passed (atol=1.5, rtol=3e1 against RMS 5.1e3 outputs). Replaced with a tolerance DERIVED from the one physical error source (q8_1 activation rounding), plus spread/magnitude preconditions. Every gate in test_gguf_mxfp4_cuda.py now has an off-GPU test proving it rejects a zeroed and a sign-flipped output, including the refuted baseline executed as its own test. - sgl-project#512 (audit sgl-project#506 A1-1): the GGUF MoE MMQ kernel's expert-address byte stride (moe.cuh) was declared `int` (32-bit) while the call site already passed int64_t -- wraps negative once a rank's per-layer expert tensor passes 2 GiB (DSV4-Flash Q4_K, 256 experts, first bad local expert 227; TP=3 sharding is the only reason this rig never hit it). Widened to int64_t through all instantiations. - sgl-project#518: three GGUF capability probes (ggml_moe_get_block_size, ggml_mmvq_kq_tuned, ggml_mxfp4_native) were registered for a DEVICE dispatch key but take no tensor argument, so the dispatcher can never route them -- every call raised "no tensor arguments" before any kernel ran, on every arch. Serving never noticed because gguf.py had grown a python mirror around the raise. Fixed with the same keyless m.impl pattern apply_token_bitmask_inplace_cuda already uses. test_no_tensor_op_dispatch_518.py pins it twice: the dispatcher behaviour on throwaway in-process ops (executed, off-GPU, no wheel needed) and a ratchet over every TORCH_LIBRARY_FRAGMENT schema. FEATURE_CATALOG.md §12 conflict as expected (both this branch and the already-merged sgl-project#510/sgl-project#513 insert a new family paragraph immediately after the §12 header): kept all three additive paragraphs in sequence (Unauthenticated-state-change sgl-project#510, Incomplete-cache-key sgl-project#513, Unreachable-registration sgl-project#81/sgl-project#518, Byte-stride width sgl-project#109/sgl-project#112/sgl-project#512, Tolerance-that-cannot-fail sgl-project#380/sgl-project#511). All 17 sections and every other previously-preserved additive paragraph verified present. Tests (CUDA_VISIBLE_DEVICES=99, PYTHONPATH pinned to this worktree, no wheel rebuild): - The three sgl-project#511-touched test files directly: 29 passed, 14 skipped (the CUDA-gated MXFP4 kernel cases correctly skip without a rebuilt wheel; the off-GPU can-discriminate portions all run and pass). - test/registered/unit/quantization/ (full): 6 failed, 100 passed, 14 skipped, 27 subtests -- all 6 failures confined to test_gguf_dequant_scratch_budget.py, untouched by sgl-project#511's diff. - test/registered/unit/layers/ (full): 3 failed, 646 passed, 39 skipped, 995 subtests -- all 3 failures in test_deterministic_fp8_gemm.py / test_flashinfer_workspace_zeroing.py, both untouched by sgl-project#511's diff. - test/registered/unit/model_loader/ (full, since gguf.py is touched): 32 failed, 229 passed, 9 skipped, 41 subtests. Diffed the FULL failing-test-ID list (not just the tail) against the pre-sgl-project#511 tip (post-sgl-project#514): BYTE-IDENTICAL, 32 lines each side, empty diff. An earlier truncated `tail` comparison looked different due to test-order variance in what scrolled past -- re-verified against the complete list before trusting it. - ruff check --select=F401,F821,UP037: clean. - codespell: clean on all 9 touched/added files including the .cc/.cuh sources.
… pool -- established unreachable, not fixed sgl-project#487 audits whether the stock even-DCP allocator branch (model_runner_kv_cache_mixin.py, the else of the allocator chain -- which inflates both index space and page granularity by dcp_size, assuming a token-sharded pool) can ever run against a draft worker at --draft-kv-layout replicated (the default), whose pool sizing has the opposite geometry (draft_pool_is_replicated) and which the allocator selection never mentions. sgl-project#108 never audited this crossing. Answer established WITHOUT a boot, by enumerating every producer of is_draft_worker=True rather than assuming there is one shape: UNREACHABLE on CUDA. Given dcp_size > 1 the stock branch is taken exactly when rank_tp_ratio is None and not weightless_kv_active(); (1) a speculative draft worker cannot exist in that shape because ServerArgs._handle_dcp_validation refuses dcp_size>1 + speculation on CUDA unless the boot is uneven-weighted DCP or the weightless fast lane; (2) a sgl-project#274 dual-group-lane runner also sets is_draft_worker=True and is NOT speculative, so leg 1 misses it -- closed instead by _lane_server_args_view forcing view.dcp_size = 1. Leg 2 exists only because "a draft pool implies a speculative algorithm" turned out false once the producer set was enumerated, not assumed -- the new falsifier pins that set so a third producer lands as a red test instead of a wrong address. Residual, named rather than fixed: on HIP/ROCm leg 1 does not run (is_hip() short-circuits before the CUDA branch), so the crossing IS admitted there -- left alone, since this fork does not serve ROCm and a desk-guessed change to address computation is exactly the sgl-project#345 right-token/wrong-slot class waiting to happen. Also folds in docs(sgl-project#482): the ARM3_COMPUTE work-matched counter rule and its script updates (scripts/dev/394_s2_proof/). FEATURE_CATALOG.md §12 conflict as expected (this branch and the already-merged sgl-project#510/sgl-project#513/sgl-project#511 all insert a new family paragraph at the same point, right after the §12 header): kept all six additive paragraphs in sequence (Unauthenticated-state-change sgl-project#510, Incomplete-cache-key sgl-project#513, Unreachable-registration sgl-project#81/sgl-project#518, Byte-stride width sgl-project#109/sgl-project#112/sgl-project#512, Tolerance-that-cannot-fail sgl-project#380/sgl-project#511, Reach-before-fix sgl-project#487). All 17 sections and every other previously-preserved additive paragraph (two-axis §1, matrix doctrine §2, sgl-project#514's five families, sgl-project#499's resolution-ordering, MERGE-DUTY owner-sites + SITREP §12, NVENC §13) verified present. Tests (CUDA_VISIBLE_DEVICES=99, PYTHONPATH pinned to this worktree): - test_stock_dcp_allocator_reach_487.py alone: 20 passed. - test/registered/unit/distributed/ (full, since model_runner_kv_cache_mixin.py is touched): 24 failed, 2167 passed, 8 skipped, 723 subtests -- same 24 failing test IDs as the established baseline, byte-identical; the +20/+2 deltas are exactly this merge's own new test file. - ruff check --select=F401,F821,UP037: clean. - codespell: clean on all 8 touched/added files.



Adding support for the Yi-VL Model: https://huggingface.co/01-ai/Yi-VL-6B
Note, since the original repo does not have a very friendly format, I moved the files and created my own config which makes it more compatible with the SGLang codebase. This allows us to load the model, tokenizer, and processor without much code change.
To test, simply call:
Link to huggingface repo compatible with this commit:
6B model: https://huggingface.co/BabyChou/Yi-VL-6B
34B model: https://huggingface.co/BabyChou/Yi-VL-34B