# syntax=docker/dockerfile:1.7
# Qwen3.8-Flash-Next-NVFP4 on DGX Spark (SM121 / GB10).
#
# Base: lmsysorg/sglang:qwen38flashnext — SGLang day-0 for qwen4_exp (arm64,
# model support = sgl-project/sglang PR #36497 baked in). It CANNOT serve this
# model on GB10 stock: QSA's packed varlen decode resolves to flash-attn-4
# CuTe-DSL kernels that fail MLIR compilation on SM121.
#
# This layer swaps in a Triton FlashDecoding-style fallback (CUDA-graph-safe)
# for non-SM100 devices. Provenance + validation:
#   https://github.com/MiaAI-Lab/Qwen3.8-Flash-Next-Dual-DGX-Sparks
#   (validated end-to-end TP=2 over RoCE on this cluster; single + 2-node
#   dummy boots with prefill, decode CUDA graphs and NEXTN spec decode).

ARG BASE_IMAGE
FROM ${BASE_IMAGE}

# The Triton fallback kernel (installed next to the QSA backend).
COPY patches/qsa_fa_fallback.py \
    /sgl-workspace/sglang/python/sglang/srt/layers/attention/qsa_fa_fallback.py

# Inject the SM121 early-return into the QSA varlen resolver.
COPY patches/patch_qsa_sm121.py /tmp/patch_qsa_sm121.py
RUN set -eux; \
    SRC="$(python3 -c 'import sglang, os; print(sglang.__path__[0])')"; \
    python3 /tmp/patch_qsa_sm121.py --check; \
    python3 /tmp/patch_qsa_sm121.py; \
    python3 /tmp/patch_qsa_sm121.py --check; \
    python3 -m py_compile \
        "$SRC/srt/layers/attention/qwen_sparse_attn_backend.py" \
        "$SRC/srt/layers/attention/qsa_fa_fallback.py"; \
    rm -f /tmp/patch_qsa_sm121.py
