{"record":{"id":"b5e8246d5b205451","repo":"sgl-project/sglang","slug":"vis-freqs-cis-is-required-for-fused-qk-norm-rope","errorCode":null,"errorMessage":"vis_freqs_cis is required for fused QK-Norm + RoPE kernel","messagePattern":"vis_freqs_cis is required for fused QK-Norm \\+ RoPE kernel","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/models/dits/joy_image.py","lineNumber":253,"sourceCode":"            txt_mod1_shift,\n            txt_mod1_scale,\n            txt_mod1_gate,\n            txt_mod2_shift,\n            txt_mod2_scale,\n            txt_mod2_gate,\n        ) = self.txt_mod(vec)\n\n        # Image attention\n        img_modulated = self.fused_modulate_img_norm1(\n            img, shift=img_mod1_shift, scale=img_mod1_scale\n        )\n        img_qkv, _ = self.img_attn_qkv(img_modulated)\n        img_q, img_k, img_v = rearrange(\n            img_qkv, \"B L (K H D) -> K B L H D\", K=3, H=self.local_heads_num\n        )\n\n        if vis_freqs_cis is None:\n            raise ValueError(\n                \"vis_freqs_cis is required for fused QK-Norm + RoPE kernel\"\n            )\n        if not (isinstance(vis_freqs_cis, torch.Tensor) and vis_freqs_cis.dim() == 2):\n            raise ValueError(\"vis_freqs_cis must be a 2D cos_sin_cache tensor\")\n        if img_q.dtype not in (torch.float16, torch.bfloat16):\n            raise ValueError(\n                f\"Fused QK-Norm + RoPE kernel only supports float16/bfloat16, but got {img_q.dtype}\"\n            )\n        img_q = img_q.contiguous()\n        img_k = img_k.contiguous()\n        img_q, img_k = apply_qk_norm_with_optional_rope(\n            q=img_q,\n            k=img_k,\n            q_norm=self.img_attn_q_norm,\n            k_norm=self.img_attn_k_norm,\n            head_dim=img_q.shape[-1],\n            cos_sin_cache=vis_freqs_cis,\n            is_neox=False,","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/dits/joy_image.py#L235-L271","documentation":"Joy image DiT's single-stream block uses a fused QK-Norm + RoPE kernel for the image branch that requires the precomputed rotary cos_sin cache. If forward is called with vis_freqs_cis=None, this ValueError is raised before the fused kernel invocation.","triggerScenarios":"Calling the joy_image block forward without the vis_freqs_cis argument — e.g. a custom pipeline that precomputes text freqs but forgets the vision-side cache, or passing None as a placeholder.","commonSituations":"Writing a standalone test/harness for the block without building the RoPE cache; refactors that thread freqs_cis through kwargs and drop the vis_ one.","solutions":["Pass the precomputed 2D vis cos_sin cache (vis_freqs_cis) to forward","Build the cache from the model's rotary embedding with the correct max sequence length before the denoising loop","Use the pipeline code provided with joy_image which constructs and forwards both freqs_cis tensors"],"exampleFix":"# before\nout = block(hidden_states, ..., txt_freqs_cis=f, vis_freqs_cis=None)\n\n# after\nvis_freqs_cis = rotary_emb.get_freqs_cis(seq_len_img).to(device)\nout = block(hidden_states, ..., txt_freqs_cis=f, vis_freqs_cis=vis_freqs_cis)","handlingStrategy":"validation","validationCode":"assert vis_freqs_cis is not None, 'vis_freqs_cis required for fused QK-Norm+RoPE'","typeGuard":"def has_vis_freqs(vis_freqs_cis) -> bool:\n    return vis_freqs_cis is not None","tryCatchPattern":null,"preventionTips":["Precompute both text and vision rope caches at pipeline start","Assert all required caches exist before entering the denoise loop"],"tags":["runtime","rope","missing-argument","diffusion"],"backgroundTag":"missing-required-argument","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}