> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sglang.io/llms.txt
> Use this file to discover all available pages before exploring further.

# FLUX.3

> Serve FLUX.3 Image Klein text-to-image generation and image editing with SGLang Diffusion.

export const ComfyUISupport = ({model = "video", note}) => {
  const PLUGIN_PATH = "python/sglang/multimodal_gen/apps/ComfyUI_SGLDiffusion";
  const PLUGIN_URL = "https://github.com/sgl-project/sglang/tree/main/" + PLUGIN_PATH;
  const MODELS = {
    flux: {
      serverNode: "SGLDiffusion Generate Image",
      integratedKey: "flux",
      workflow: "flux_sgld_sp.json"
    },
    "z-image": {
      serverNode: "SGLDiffusion Generate Image",
      integratedKey: "lumina2",
      workflow: "z-image_sgld.json"
    },
    "qwen-image": {
      serverNode: "SGLDiffusion Generate Image",
      integratedKey: "qwen_image",
      workflow: "qwen_image_sgld.json"
    },
    "qwen-image-edit": {
      serverNode: "SGLDiffusion Generate Image",
      integratedKey: "qwen_image_edit",
      note: "Image editing through the integrated path is experimental."
    },
    "minimax-h3": {
      serverNode: "SGLDiffusion Generate H3",
      verified: true,
      integratedBlockedBecause: "H3 denoises a packed video-and-audio sequence in one pass and routes " + "conditioning by task, while ComfyUI's KSampler drives a single latent " + "tensor and has no audio branch"
    },
    image: {
      serverNode: "SGLDiffusion Generate Image"
    },
    video: {
      serverNode: "SGLDiffusion Generate Video"
    }
  };
  const spec = MODELS[model] || MODELS.video;
  const extraNote = note || spec.note;
  return <div>
      <p>
        Run this model from ComfyUI with the{" "}
        <a href={PLUGIN_URL}>SGLDiffusion plugin</a>, which ships in the SGLang
        repository at <code>{PLUGIN_PATH}</code>.
      </p>

      <p>
        <strong>Server mode</strong> — SGLang runs the pipeline and ComfyUI
        sends the request. Start a server as shown above, point the{" "}
        <code>SGLDiffusion Server Model</code> node at it, then generate with{" "}
        <code>{spec.serverNode}</code>.
        {spec.verified ? " This path has been run end to end against a live server." : ""}
      </p>

      {spec.integratedKey ? <p>
          <strong>Integrated mode</strong> — ComfyUI's own sampler, CLIP, and
          VAE drive the loop while SGLang replaces the model forward. Load the
          checkpoint with <code>SGLDiffusion UNET Loader</code> and set{" "}
          <code>model_type</code> to <code>{spec.integratedKey}</code> on the{" "}
          <code>SGLDiffusion Options</code> node.
          {spec.workflow ? <>
              {" "}
              A reference workflow is included at{" "}
              <code>{`${PLUGIN_PATH}/workflows/${spec.workflow}`}</code>.
            </> : null}
        </p> : <p>
          <strong>Integrated mode</strong> — not available for this model
          {spec.integratedBlockedBecause ? `: ${spec.integratedBlockedBecause}` : ", which has no executor in the plugin"}
          . Use server mode.
        </p>}

      {extraNote ? <p>{extraNote}</p> : null}
    </div>;
};

export const config = (() => {
  const modelOf = s => s.variant === "distilled" ? "black-forest-labs/flux-3-image-klein" : "black-forest-labs/flux-3-image-klein-base";
  const hardware = [{
    id: "rtx5090",
    label: "RTX 5090",
    vram: "32GB",
    vendor: "consumer"
  }, {
    id: "rtx6000pro",
    label: "RTX PRO 6000 Blackwell",
    vram: "96GB",
    vendor: "consumer"
  }];
  const hardwareLabels = {
    rtx5090: "RTX 5090",
    rtx6000pro: "RTX PRO 6000",
    h100: "H100",
    h200: "H200",
    b200: "B200",
    b300: "B300",
    gb200: "GB200",
    gb300: "GB300"
  };
  return {
    modelName: "FLUX.3",
    supportedHardware: Object.keys(hardwareLabels),
    hardware,
    groupHardware: true,
    matchDims: [],
    overlayDims: [{
      id: "mode",
      title: "Request mode",
      scope: "request",
      description: "One server serves both; a request with a reference image is an edit.",
      default: "t2i",
      options: [{
        id: "t2i",
        label: "Text to image",
        flags: []
      }, {
        id: "i2i",
        label: "Image to image",
        flags: []
      }]
    }, {
      id: "variant",
      title: "Model",
      scope: "serve",
      description: "Base and distilled are self-contained repositories. Base uses CFG; distilled is a flow map without CFG.",
      default: "base",
      options: [{
        id: "distilled",
        label: "Distilled",
        subtitle: "16-step flow map, no CFG",
        flags: []
      }, {
        id: "base",
        label: "Base",
        subtitle: "50-step CFG",
        flags: []
      }]
    }, {
      id: "quant",
      title: "Precision",
      scope: "serve",
      description: "FP8R and NVFP4 load a quantized DiT from variants/. Text encoder and VAE precision follow the package configuration.",
      default: "bf16",
      options: [{
        id: "bf16",
        label: "BF16",
        subtitle: "Reference",
        flags: []
      }, {
        id: "fp8r",
        label: "FP8R",
        subtitle: "Rowwise FP8 DiT",
        flags: []
      }, {
        id: "nvfp4",
        label: "NVFP4",
        subtitle: "Blackwell, FP4 DiT",
        flags: [],
        disabled: s => ["h100", "h200"].includes(s.hw),
        disableReason: "NVFP4 GEMMs need a Blackwell GPU.",
        soft: true,
        softReason: "Verify quantized-output fidelity for your workload."
      }]
    }, {
      id: "placement",
      title: "Placement",
      scope: "serve",
      docsHref: "/docs/sglang-diffusion/api/cli#component-residency",
      description: "A 1 MP, batch-1 workload fits resident on RTX 5090. Larger references or batches need additional headroom; use auto or offload when necessary.",
      default: "auto",
      options: [{
        id: "auto",
        label: "Auto",
        recommended: true,
        flags: []
      }, {
        id: "offload",
        label: "CPU offload",
        flags: ["--component-residency transformer=layerwise-offload,text_encoder=component-offload,vae=component-offload"],
        recommendedWhen: s => s.hw === "rtx5090" && Number(s.batch_size) > 1
      }, {
        id: "resident",
        label: "GPU resident",
        flags: ["--component-residency all=resident"],
        recommendedWhen: s => s.hw !== "rtx5090" || Number(s.batch_size) === 1
      }]
    }, {
      id: "attention",
      title: "Attention",
      scope: "serve",
      default: "auto",
      description: "Keep the backend fixed for numerical comparisons.",
      options: [{
        id: "auto",
        label: "Platform default",
        flags: [],
        recommended: true
      }, {
        id: "sdpa",
        label: "Torch SDPA",
        flags: ["--attention-backend torch_sdpa"]
      }, {
        id: "fa",
        label: "FlashAttention",
        flags: ["--attention-backend fa"]
      }]
    }, {
      id: "execution",
      title: "Execution",
      scope: "serve",
      default: "eager",
      description: "CUDA graphs can reduce launch overhead but reserve additional memory.",
      options: [{
        id: "eager",
        label: "Eager",
        flags: [],
        recommended: true
      }, {
        id: "bcg",
        label: "Breakable CUDA graphs",
        flags: ["--enable-breakable-cuda-graph"],
        soft: true,
        softReason: "Not verified for every hardware and topology."
      }]
    }, {
      id: "batch_size",
      title: "Max batch size",
      scope: "serve",
      kind: "number",
      min: 1,
      max: 8,
      default: 1,
      unit: "requests",
      options: [],
      description: "Larger batches trade activation memory and request latency for throughput."
    }, {
      id: "batch_delay",
      title: "Batch window",
      scope: "serve",
      kind: "number",
      min: 0,
      max: 100,
      default: 5,
      unit: "ms",
      options: [],
      showWhen: s => Number(s.batch_size) > 1
    }, {
      id: "quality",
      title: "Quality",
      scope: "request",
      default: "lossless",
      description: "Quantization and Cache-DiT remain separate, potentially lossy choices.",
      options: [{
        id: "lossless",
        label: "Lossless"
      }, {
        id: "exact",
        label: "Exact"
      }]
    }, {
      id: "resolution",
      title: "Resolution",
      scope: "request",
      showWhen: s => s.mode !== "i2i",
      default: "1024",
      options: [{
        id: "1024",
        label: "1024×1024",
        flags: [],
        recommended: true
      }]
    }, {
      id: "schedule",
      title: "Sampling",
      scope: "request",
      showWhen: s => s.variant !== "distilled",
      default: "quality",
      options: [{
        id: "quality",
        label: "Quality · 50-step, CFG 3.5",
        flags: [],
        recommended: true
      }]
    }, {
      id: "outputs",
      title: "Outputs",
      scope: "request",
      kind: "number",
      min: 1,
      max: 4,
      unit: "outputs per prompt",
      default: 1,
      options: []
    }],
    commandBuilder: {
      defaultSelection: {
        hw: "rtx5090",
        nodes: 1,
        gpus_per_node: 1,
        topology_mode: "auto",
        tp_size: 1,
        ulysses_degree: 1,
        ring_degree: 1
      },
      resource: {
        limits: {
          nodes: {
            min: 1,
            max: 1
          },
          gpus_per_node: {
            min: 1,
            max: 8
          }
        },
        verifiedRecipes: [{
          id: "gb300-base-bf16",
          hw: "gb300",
          nodes: 1,
          gpus_per_node: 1,
          tp_size: 1,
          ulysses_degree: 1,
          ring_degree: 1,
          variant: "base",
          quant: "bf16",
          placement: "resident",
          attention: "fa",
          execution: "eager",
          quality: "exact",
          batch_size: 1,
          outputs: 1,
          default: true
        }],
        autoTopology: s => ({
          tp_size: Number(s.gpus_per_node) || 1,
          ulysses_degree: 1,
          ring_degree: 1
        }),
        validateTopology: (s, t) => {
          const errors = [];
          const gpus = Number(s.gpus_per_node);
          if (Number(s.nodes) !== 1 || !Number.isInteger(gpus) || gpus < 1 || gpus > 8) {
            errors.push("Choose one node with one to eight GPUs.");
          }
          if (![t.tp_size, t.ulysses_degree, t.ring_degree].every(n => Number.isInteger(n) && n > 0)) {
            errors.push("Parallel degrees must be positive integers.");
          }
          if (24 % Number(t.tp_size) || 24 / Number(t.tp_size) % Number(t.ulysses_degree)) {
            errors.push("TP and Ulysses must partition the 24 attention heads evenly.");
          }
          if (Number(t.ring_degree) !== 1) {
            errors.push("FLUX.3 sequence parallel uses Ulysses only (ring degree 1).");
          }
          if (Number(t.tp_size) * Number(t.ulysses_degree) !== gpus) {
            errors.push("TP size x Ulysses degree must equal the GPU count.");
          }
          return errors;
        }
      },
      resolveDeployment: s => {
        const resource = config.commandBuilder.resource;
        const topology = s.topology_mode === "manual" ? {
          tp_size: Number(s.tp_size),
          ulysses_degree: Number(s.ulysses_degree),
          ring_degree: Number(s.ring_degree)
        } : resource.autoTopology(s);
        const errors = resource.validateTopology(s, topology);
        const gpus = Number(s.gpus_per_node) || 1;
        const parallel = [];
        if (gpus > 1) parallel.push(`--num-gpus ${gpus}`, `--tp-size ${topology.tp_size}`);
        if (topology.ulysses_degree > 1) parallel.push(`--ulysses-degree ${topology.ulysses_degree}`);
        if (s.quant !== "bf16") parallel.push(`--model-variant ${s.quant}`);
        if (Number(s.batch_size) > 1) {
          parallel.push(`--batching-max-size ${Number(s.batch_size)}`, `--batching-delay-ms ${Number(s.batch_delay) || 0}`);
        }
        const testedProfile = ["gb300", "h200"].includes(s.hw) && s.attention === "fa" && ["base", "distilled"].includes(s.variant) && (s.quant === "bf16" || s.quality === "exact") && (s.hw === "gb300" || s.quant !== "nvfp4") || s.hw === "rtx5090" && s.attention === "sdpa" && s.variant === "base" && s.quant === "bf16";
        const verified = testedProfile && gpus === 1 && s.placement === "resident" && s.execution === "eager" && ["exact", "lossless"].includes(s.quality) && Number(s.batch_size) === 1 && Number(s.outputs) === 1;
        const warnings = verified ? [] : ["This exact hardware, checkpoint and topology combination is not yet end-to-end verified."];
        if (s.hw === "rtx5090" && s.placement === "resident" && Number(s.batch_size) > 1) {
          warnings.push("Full-resolution batching needs additional activation memory. Use offload or batch 1 if the resident batch does not fit.");
        }
        return {
          match: {
            hw: s.hw
          },
          nnodes: 1,
          verified: verified && !errors.length,
          verificationStatus: errors.length ? "error" : verified ? "verified" : "unverified",
          env: [],
          flags: [`--model-path ${modelOf(s)}`, ...parallel, "--host {{HOST_IP}}", "--port {{PORT}}"],
          builder: {
            topology,
            topologySummary: `${Number(s.gpus_per_node) || 1}× ${hardwareLabels[s.hw] || s.hw}`,
            errors,
            warnings,
            verification: {
              serve: errors.length ? "error" : verified ? "verified" : "unverified",
              request: errors.length ? "error" : verified ? "verified" : "unverified"
            },
            resolvedSettings: {
              placement: s.placement === "resident" ? "GPU resident" : s.placement === "offload" ? "Layerwise offload" : "Auto"
            }
          }
        };
      }
    },
    modelNames: {
      ...Object.fromEntries(["base", "distilled"].flatMap(variant => ["bf16", "fp8r", "nvfp4"].map(quant => [`${variant}|${quant}`, modelOf({
        variant
      })]))),
      default: modelOf({
        variant: "base"
      })
    },
    placeholders: {
      HOST_IP: {
        target: "command",
        label: "Bind host",
        default: "0.0.0.0"
      },
      PORT: {
        target: "command",
        label: "Bind port",
        default: "30010"
      },
      CURL_HOST: {
        target: "curl",
        label: "Server host",
        default: "localhost"
      },
      CURL_PORT: {
        target: "curl",
        label: "Server port",
        default: "30010"
      },
      INPUT_IMAGE: {
        target: "curl",
        label: "I2I input image",
        default: "/data/flux3/reference.png"
      }
    },
    curl: s => {
      const common = {
        prompt: s.mode === "i2i" ? "Render the reference as a winter wildlife photograph" : "A red fox standing in fresh snow",
        ...s.mode === "i2i" ? {} : {
          size: "1024x1024"
        },
        ...s.variant === "base" ? {
          num_inference_steps: 50,
          guidance_scale: 3.5
        } : {},
        seed: 0,
        quality: s.quality,
        n: Number(s.outputs) || 1,
        response_format: "b64_json"
      };
      if (s.mode === "i2i") {
        const fields = Object.entries(common).map(([key, value]) => `  -F "${key}=${value}" \\`).join("\n");
        return `curl -sS -X POST http://{{CURL_HOST}}:{{CURL_PORT}}/v1/images/edits \\
  -F "image=@{{INPUT_IMAGE}}" \\
${fields}
  -o flux3_i2i.json`;
      }
      const request = common;
      return `curl -sS -X POST http://{{CURL_HOST}}:{{CURL_PORT}}/v1/images/generations \\
  -H 'Content-Type: application/json' \\
  -d '${JSON.stringify(request, null, 2)}' \\
  -o flux3_t2i.json`;
    },
    runModes: () => ["python"],
    showPlaygroundLink: false,
    cells: []
  };
})();

export const Deployment = ({config, benchmarks, agenticLink}) => {
  if (!config) {
    return <div style={{
      padding: 12,
      color: "#b91c1c"
    }}>Deployment: missing <code>config</code> prop</div>;
  }
  const AMD_RDMA_DOCKER_FLAGS = ["--device /dev/infiniband", "--cap-add IPC_LOCK", "--ulimit memlock=-1", "--ulimit stack=67108864", "--ulimit nofile=1048576:1048576"];
  const HARDWARE_CATALOG = {
    blackwell: [{
      id: "b300",
      label: "B300",
      vram: "288GB"
    }, {
      id: "gb300",
      label: "GB300",
      vram: "288GB"
    }, {
      id: "b200",
      label: "B200",
      vram: "192GB"
    }, {
      id: "gb200",
      label: "GB200",
      vram: "192GB"
    }, {
      id: "dgx-spark",
      label: "DGX Spark",
      vram: "128GB",
      multiNodeDockerFlags: ["--ulimit memlock=-1:-1", "--cap-add IPC_LOCK", "--device /dev/infiniband"]
    }],
    hopper: [{
      id: "h200",
      label: "H200",
      vram: "141GB"
    }, {
      id: "h100",
      label: "H100",
      vram: "80GB"
    }, {
      id: "h20-3e",
      label: "H20-3e",
      vram: "141GB"
    }, {
      id: "h800",
      label: "H800",
      vram: "80GB"
    }],
    amd: [{
      id: "mi300x",
      label: "MI300X",
      vram: "192GB",
      multiNodeDockerFlags: [...AMD_RDMA_DOCKER_FLAGS]
    }, {
      id: "mi325x",
      label: "MI325X",
      vram: "256GB",
      multiNodeDockerFlags: [...AMD_RDMA_DOCKER_FLAGS]
    }, {
      id: "mi350x",
      label: "MI350X",
      vram: "288GB",
      multiNodeDockerFlags: [...AMD_RDMA_DOCKER_FLAGS]
    }, {
      id: "mi355x",
      label: "MI355X",
      vram: "288GB",
      multiNodeDockerFlags: [...AMD_RDMA_DOCKER_FLAGS]
    }],
    npu: [{
      id: "a3",
      label: "A3 Series",
      vram: "64GB/die",
      npuDevices: 16
    }, {
      id: "a5",
      label: "950PR/DT Series",
      vram: "128GB",
      npuDevices: 8
    }]
  };
  const makeStyles = isDark => ({
    container: {
      maxWidth: "900px",
      margin: "0 auto",
      display: "flex",
      flexDirection: "column",
      gap: "3px"
    },
    card: {
      padding: "5px 10px",
      border: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`,
      borderLeft: `3px solid ${isDark ? "#E85D4D" : "#D45D44"}`,
      borderRadius: "4px",
      display: "flex",
      alignItems: "center",
      gap: "10px",
      background: isDark ? "#1f2937" : "#fff"
    },
    cardColumn: {
      padding: "5px 10px",
      border: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`,
      borderLeft: `3px solid ${isDark ? "#E85D4D" : "#D45D44"}`,
      borderRadius: "4px",
      display: "flex",
      flexDirection: "column",
      gap: "4px",
      background: isDark ? "#1f2937" : "#fff"
    },
    title: {
      fontSize: "12px",
      fontWeight: "600",
      minWidth: "108px",
      flexShrink: 0,
      color: isDark ? "#e5e7eb" : "inherit"
    },
    vendorRow: {
      display: "flex",
      alignItems: "center",
      gap: "6px"
    },
    vendorLabel: {
      fontSize: "10px",
      fontWeight: "600",
      color: isDark ? "#9ca3af" : "#6b7280",
      width: "68px",
      flexShrink: 0,
      textTransform: "uppercase",
      letterSpacing: "0.04em"
    },
    itemsGrid: () => ({
      display: "grid",
      gridTemplateColumns: "repeat(auto-fit, minmax(72px, 1fr))",
      gap: "4px",
      flex: 1
    }),
    labelBase: {
      padding: "2px 8px",
      border: `1px solid ${isDark ? "#9ca3af" : "#d1d5db"}`,
      borderRadius: "3px",
      cursor: "pointer",
      display: "inline-flex",
      flexDirection: "column",
      alignItems: "center",
      justifyContent: "center",
      fontWeight: "500",
      fontSize: "12px",
      transition: "all 0.2s",
      userSelect: "none",
      minHeight: "26px",
      textAlign: "center",
      background: isDark ? "#374151" : "#fff",
      color: isDark ? "#e5e7eb" : "inherit"
    },
    checked: {
      background: "#D45D44",
      color: "white",
      borderColor: "#D45D44"
    },
    disabled: {
      cursor: "not-allowed",
      opacity: 0.4
    },
    subtitle: {
      display: "block",
      fontSize: "9px",
      marginTop: "1px",
      lineHeight: "1.1",
      opacity: 0.7
    },
    commandWrap: {
      position: "relative",
      flex: 1,
      background: isDark ? "#111827" : "#f5f5f5",
      borderRadius: "6px",
      border: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`,
      overflow: "hidden"
    },
    commandHeader: {
      display: "flex",
      flexWrap: "wrap",
      justifyContent: "space-between",
      alignItems: "center",
      gap: "6px 10px",
      padding: "6px 10px",
      borderBottom: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`,
      background: isDark ? "#1f2937" : "#fafafa"
    },
    commandPre: {
      padding: "12px 16px",
      fontFamily: "'Menlo', 'Monaco', 'Courier New', monospace",
      fontSize: "12px",
      lineHeight: "1.5",
      color: isDark ? "#e5e7eb" : "#374151",
      whiteSpace: "pre-wrap",
      overflowX: "auto",
      margin: 0
    },
    mtpWarn: {
      margin: "8px 0 0",
      padding: "8px 12px",
      borderRadius: "8px",
      fontSize: "12px",
      lineHeight: "1.45",
      background: isDark ? "#78350f" : "#fef3c7",
      color: isDark ? "#fde68a" : "#92400e",
      border: `1px solid ${isDark ? "#92400e" : "#fcd34d"}`
    },
    badge: status => ({
      display: "inline-flex",
      alignItems: "center",
      gap: "6px",
      padding: "2px 8px",
      borderRadius: "10px",
      background: ({
        verified: isDark ? "#064e3b" : "#d1fae5",
        "in-progress": isDark ? "#1e3a8a" : "#dbeafe",
        unverified: isDark ? "#78350f" : "#fef3c7"
      })[verifyStatusOf(status)],
      color: ({
        verified: isDark ? "#a7f3d0" : "#065f46",
        "in-progress": isDark ? "#bfdbfe" : "#1e40af",
        unverified: isDark ? "#fde68a" : "#92400e"
      })[verifyStatusOf(status)],
      fontSize: "11px",
      fontWeight: 600,
      whiteSpace: "nowrap"
    }),
    badgeDot: status => ({
      width: "8px",
      height: "8px",
      borderRadius: "50%",
      background: ({
        verified: "#10b981",
        "in-progress": "#3b82f6",
        unverified: "#f59e0b"
      })[verifyStatusOf(status)]
    }),
    iconButton: {
      padding: "4px 10px",
      border: `1px solid ${isDark ? "#4b5563" : "#d1d5db"}`,
      borderRadius: "4px",
      background: isDark ? "#1f2937" : "#fff",
      color: isDark ? "#e5e7eb" : "#374151",
      fontSize: "11px",
      fontWeight: 500,
      cursor: "pointer",
      display: "inline-flex",
      alignItems: "center",
      gap: "4px"
    },
    iconRow: {
      display: "inline-flex",
      flexWrap: "wrap",
      gap: "6px"
    },
    runModeWrap: {
      display: "inline-flex",
      border: `1px solid ${isDark ? "#4b5563" : "#d1d5db"}`,
      borderRadius: "10px",
      overflow: "hidden",
      fontSize: "11px",
      fontWeight: 600,
      userSelect: "none"
    },
    runModeChip: active => ({
      padding: "2px 10px",
      cursor: "pointer",
      background: active ? isDark ? "#1f2937" : "#fff" : "transparent",
      color: active ? isDark ? "#e5e7eb" : "#111827" : isDark ? "#9ca3af" : "#6b7280",
      borderRight: `1px solid ${isDark ? "#4b5563" : "#d1d5db"}`
    }),
    runModeChipLast: active => ({
      padding: "2px 10px",
      cursor: "pointer",
      background: active ? isDark ? "#1f2937" : "#fff" : "transparent",
      color: active ? isDark ? "#e5e7eb" : "#111827" : isDark ? "#9ca3af" : "#6b7280"
    }),
    headerLeft: {
      display: "inline-flex",
      flexWrap: "wrap",
      alignItems: "center",
      gap: "8px"
    },
    modalBackdrop: {
      position: "fixed",
      inset: 0,
      background: "rgba(0,0,0,0.5)",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      zIndex: 9999
    },
    modalBox: {
      background: isDark ? "#1f2937" : "#fff",
      color: isDark ? "#e5e7eb" : "#111827",
      borderRadius: "8px",
      padding: "20px",
      maxWidth: "720px",
      width: "92%",
      maxHeight: "85vh",
      overflowY: "auto",
      border: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`,
      boxShadow: "0 10px 25px rgba(0,0,0,0.25)"
    },
    modalHeader: {
      display: "flex",
      justifyContent: "space-between",
      alignItems: "center",
      marginBottom: "12px"
    },
    modalTitle: {
      fontSize: "15px",
      fontWeight: 600
    },
    modalCloseBtn: {
      background: "transparent",
      border: "none",
      color: "inherit",
      fontSize: "20px",
      cursor: "pointer",
      padding: "0 6px",
      lineHeight: 1
    },
    formField: {
      display: "flex",
      flexDirection: "column",
      gap: "4px",
      marginBottom: "10px"
    },
    formLabel: {
      fontSize: "12px",
      fontWeight: 500,
      color: isDark ? "#9ca3af" : "#4b5563"
    },
    formInput: {
      padding: "6px 10px",
      fontSize: "13px",
      border: `1px solid ${isDark ? "#4b5563" : "#d1d5db"}`,
      borderRadius: "4px",
      background: isDark ? "#111827" : "#fff",
      color: isDark ? "#e5e7eb" : "#111827",
      fontFamily: "'Menlo', 'Monaco', 'Courier New', monospace"
    },
    sectionHeading: {
      fontSize: "12px",
      fontWeight: 600,
      textTransform: "uppercase",
      letterSpacing: "0.04em",
      color: isDark ? "#9ca3af" : "#6b7280",
      margin: "12px 0 6px 0"
    },
    primaryBtn: {
      padding: "6px 14px",
      background: "#D45D44",
      color: "white",
      border: "none",
      borderRadius: "4px",
      cursor: "pointer",
      fontSize: "13px",
      fontWeight: 500
    },
    benchCard: {
      padding: "8px 12px",
      border: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`,
      borderLeft: `3px solid ${isDark ? "#E85D4D" : "#D45D44"}`,
      borderRadius: "4px",
      background: isDark ? "#1f2937" : "#fff",
      display: "flex",
      flexDirection: "column",
      gap: "8px"
    },
    benchHeader: {
      display: "flex",
      flexWrap: "wrap",
      alignItems: "baseline",
      justifyContent: "space-between",
      gap: "6px 12px"
    },
    benchTitle: {
      fontSize: "13px",
      fontWeight: 600,
      color: isDark ? "#e5e7eb" : "inherit"
    },
    benchVersion: {
      fontSize: "11px",
      color: isDark ? "#9ca3af" : "#6b7280"
    },
    benchHeaderRight: {
      display: "flex",
      flexWrap: "wrap",
      alignItems: "center",
      gap: "6px 10px",
      flexShrink: 0
    },
    benchChipRow: {
      display: "flex",
      alignItems: "center",
      gap: "6px",
      flexWrap: "wrap",
      margin: "2px 0 8px"
    },
    benchChip: {
      padding: "2px 10px",
      fontSize: "12px",
      cursor: "pointer",
      border: `1px solid ${isDark ? "#4b5563" : "#d1d5db"}`,
      borderRadius: "4px",
      background: isDark ? "#1f2937" : "#fff",
      color: isDark ? "#e5e7eb" : "#374151",
      fontFamily: "'Menlo', 'Monaco', 'Courier New', monospace"
    },
    benchChipActive: {
      background: "#D45D44",
      color: "white",
      borderColor: "#D45D44"
    },
    benchBlock: {
      border: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`,
      borderRadius: "4px",
      padding: "8px 10px",
      background: isDark ? "#111827" : "#fafafa"
    },
    benchBlockTitle: {
      fontSize: "11px",
      fontWeight: 600,
      textTransform: "uppercase",
      letterSpacing: "0.04em",
      color: isDark ? "#9ca3af" : "#6b7280",
      marginBottom: "4px"
    },
    benchWorkload: {
      fontSize: "11px",
      fontStyle: "italic",
      color: isDark ? "#9ca3af" : "#6b7280",
      marginBottom: "6px",
      lineHeight: "1.3"
    },
    benchRow: {
      display: "flex",
      justifyContent: "space-between",
      fontSize: "12px",
      padding: "2px 0"
    },
    benchKey: {
      color: isDark ? "#9ca3af" : "#6b7280"
    },
    benchVal: {
      color: isDark ? "#e5e7eb" : "#111827",
      fontFamily: "'Menlo', 'Monaco', 'Courier New', monospace",
      fontWeight: 500
    },
    benchNotes: {
      fontSize: "11px",
      fontStyle: "italic",
      color: isDark ? "#9ca3af" : "#6b7280"
    },
    benchLegend: {
      fontSize: "10px",
      fontStyle: "italic",
      color: isDark ? "#6b7280" : "#9ca3af",
      marginTop: "6px",
      fontFamily: "'Menlo', 'Monaco', 'Courier New', monospace"
    },
    benchEmpty: {
      fontSize: "12px",
      fontStyle: "italic",
      color: isDark ? "#9ca3af" : "#6b7280"
    },
    benchTableScroll: {
      overflowX: "auto",
      overflowY: "hidden",
      marginTop: "4px"
    },
    benchTable: {
      display: "grid",
      columnGap: 0,
      rowGap: "3px",
      alignItems: "baseline",
      minWidth: "max-content"
    },
    benchTableHead: {
      textAlign: "right",
      fontWeight: 500,
      fontSize: "11px",
      color: isDark ? "#9ca3af" : "#6b7280",
      paddingLeft: "16px",
      paddingBottom: "4px",
      whiteSpace: "nowrap"
    },
    benchTableCornerHead: {
      paddingBottom: "4px",
      position: "sticky",
      left: 0,
      background: isDark ? "#111827" : "#fafafa",
      zIndex: 1,
      alignSelf: "stretch"
    },
    benchTableSeparator: {
      gridColumn: "1 / -1",
      height: "1px",
      background: isDark ? "#374151" : "#e5e7eb",
      marginTop: "-3px"
    },
    benchTableLabel: {
      textAlign: "left",
      fontSize: "12px",
      color: isDark ? "#9ca3af" : "#6b7280",
      whiteSpace: "nowrap",
      position: "sticky",
      left: 0,
      background: isDark ? "#111827" : "#fafafa",
      zIndex: 1
    },
    benchTableValue: {
      textAlign: "right",
      fontSize: "12px",
      color: isDark ? "#e5e7eb" : "#111827",
      fontFamily: "'Menlo', 'Monaco', 'Courier New', monospace",
      fontWeight: 500,
      paddingLeft: "16px",
      whiteSpace: "nowrap"
    },
    benchTableValueMissing: {
      color: isDark ? "#6b7280" : "#9ca3af"
    }
  });
  const VERIFY_LABEL = {
    verified: "Verified",
    "in-progress": "Final Verification In Progress",
    unverified: "Not Verified"
  };
  const verifyStatusOf = v => typeof v === "string" ? VERIFY_LABEL[v] ? v : "unverified" : v ? "verified" : "unverified";
  const cellVerifyStatus = (c, sel) => {
    if (!c) return "unverified";
    const v = typeof c.verificationStatus === "function" ? c.verificationStatus(sel) : c.verificationStatus;
    return verifyStatusOf(v ?? c.verified);
  };
  const LEGACY_MATCH_DIMS = [{
    id: "variant",
    title: "Model Variant",
    optionsKey: "variants"
  }, {
    id: "quant",
    title: "Quantization",
    optionsKey: "quantizations"
  }, {
    id: "strategy",
    title: "Strategy",
    optionsKey: "strategies"
  }, {
    id: "nodes",
    title: "Nodes",
    optionsKey: "nodesOptions"
  }];
  const matchDimSpecs = (config.matchDims || LEGACY_MATCH_DIMS).map(d => ({
    ...d,
    options: d.options || config[d.optionsKey] || []
  }));
  const overlayDimSpecs = config.overlayDims || [];
  const commandBuilder = config.commandBuilder || null;
  const DIMENSIONS = ["hw", ...matchDimSpecs.map(d => d.id)];
  const optionVisible = (opt, sel) => typeof opt.showWhen !== "function" || opt.showWhen(sel);
  const optionDisabled = (opt, sel) => typeof opt.disabled === "function" ? opt.disabled(sel) : !!opt.disabled;
  const visibleOptions = (spec, sel) => (spec.options || []).filter(o => optionVisible(o, sel));
  const rowVisible = (spec, sel) => (typeof spec.showWhen !== "function" || spec.showWhen(sel)) && visibleOptions(spec, sel).length > 0;
  const overlayPick = sel => {
    const picked = [];
    for (const spec of config.overlayDims || []) {
      if (!rowVisible(spec, sel)) continue;
      const opt = (spec.options || []).find(o => o.id === sel[spec.id]);
      if (opt && !optionDisabled(opt, sel)) picked.push(opt);
    }
    return picked;
  };
  const overlayPart = (sel, key) => {
    const out = [];
    for (const opt of overlayPick(sel)) {
      const add = typeof opt[key] === "function" ? opt[key](sel) : opt[key];
      if (add) out.push(...add);
    }
    return out;
  };
  const overlayCompose = (cellFlags, sel) => {
    const strip = overlayPart(sel, "stripPrefixes");
    const add = overlayPart(sel, "flags");
    if (!strip.length) return [...cellFlags || [], ...add];
    const used = new Set();
    const replacementsFor = tok => {
      const out = [];
      add.forEach((f, i) => {
        if (used.has(i) || f.split(/[\s=]/)[0] !== tok) return;
        used.add(i);
        out.push(f);
      });
      return out;
    };
    const out = [];
    for (const f of cellFlags || []) {
      const tok = f.split(/[\s=]/)[0];
      if (!strip.includes(tok)) out.push(f); else out.push(...replacementsFor(tok));
    }
    add.forEach((f, i) => {
      if (!used.has(i)) out.push(f);
    });
    return out;
  };
  const optionSoft = (opt, sel) => typeof opt.soft === "function" ? opt.soft(sel) : !!opt.soft;
  const findCell = (cells, sel) => {
    const cell = cells.find(c => DIMENSIONS.every(d => c.match[d] === sel[d]));
    return cell && typeof config.resolveRecipe === "function" ? config.resolveRecipe(cell, sel) : cell;
  };
  const findBenchmark = (list, sel) => {
    const hits = (list || []).filter(b => Object.entries(b.match || ({})).every(([k, v]) => sel[k] === v));
    return hits.sort((a, b) => Object.keys(b.match).length - Object.keys(a.match).length)[0] || null;
  };
  const normalizeSpeed = speed => {
    if (!speed) return [];
    return Array.isArray(speed) ? speed : [speed];
  };
  const effectiveAccuracy = (entry, sel) => entry ? {
    ...config.defaultAccuracy && config.defaultAccuracy[sel.variant] || ({}),
    ...entry.accuracy || ({})
  } : {};
  const benchmarkIsEmpty = (entry, accuracy) => {
    for (const m of normalizeSpeed(entry && entry.speed)) {
      if (m && typeof m === "object") {
        for (const [key, v] of Object.entries(m)) {
          if (key === "workload") continue;
          if (v !== null && v !== undefined) return false;
        }
      }
    }
    if (accuracy && typeof accuracy === "object") {
      for (const v of Object.values(accuracy)) {
        if (v !== null && v !== undefined) return false;
      }
    }
    return true;
  };
  const isOptionAvailable = (cells, sel, dim, value) => {
    const idx = DIMENSIONS.indexOf(dim);
    const higher = DIMENSIONS.slice(0, idx);
    return cells.some(c => c.match[dim] === value && higher.every(d => c.match[d] === sel[d]));
  };
  const snapToValidCell = (cells, sel, dim, value) => {
    const idx = DIMENSIONS.indexOf(dim);
    const higher = DIMENSIONS.slice(0, idx);
    const lower = DIMENSIONS.slice(idx + 1);
    let best = null, bestLowerMatches = -1;
    for (const c of cells) {
      if (c.match[dim] !== value) continue;
      if (!higher.every(d => c.match[d] === sel[d])) continue;
      let s = 0;
      for (const d of lower) if (c.match[d] === sel[d]) s++;
      if (s > bestLowerMatches) {
        bestLowerMatches = s;
        best = c;
      }
    }
    if (!best) return sel;
    const next = {
      ...sel,
      [dim]: value
    };
    for (const d of lower) next[d] = best.match[d];
    return next;
  };
  const validateSelection = (cells, parsed) => {
    const valid = {};
    for (const dim of DIMENSIONS) {
      const want = parsed[dim];
      const works = cells.some(c => c.match[dim] === want && DIMENSIONS.slice(0, DIMENSIONS.indexOf(dim)).every(d => c.match[d] === valid[d]));
      if (works) {
        valid[dim] = want;
      } else {
        const fallback = cells.find(c => DIMENSIONS.slice(0, DIMENSIONS.indexOf(dim)).every(d => c.match[d] === valid[d]));
        valid[dim] = fallback ? fallback.match[dim] : want;
      }
    }
    for (const spec of overlayDimSpecs) {
      const want = parsed[spec.id];
      const opts = spec.options || [];
      const picked = opts.some(o => o.id === want) ? want : (spec.default ?? (opts[0] && opts[0].id)) ?? "";
      const withPick = {
        ...valid,
        [spec.id]: picked
      };
      const usable = visibleOptions(spec, withPick).filter(o => !optionDisabled(o, withPick));
      valid[spec.id] = usable.some(o => o.id === picked) ? picked : (usable[0] && usable[0].id) ?? picked;
    }
    return valid;
  };
  const resolveModelName = sel => {
    const keys = [`${sel.hw}|${sel.variant}|${sel.quant}`, `${sel.variant}|${sel.quant}`, `${sel.hw}|${sel.quant}`, sel.quant, sel.hw, "default"];
    for (const k of keys) {
      const hit = config.modelNames[k];
      if (hit) return hit;
    }
    return "";
  };
  const interpolate = (text, env, modelName) => text.replace(/{{(\w+)}}/g, (_, key) => key === "MODEL_NAME" ? modelName : env[key] ?? `{{${key}}}`);
  const parseNnodes = id => {
    if (Number.isInteger(id)) return id;
    if ((/^\d+$/).test(id || "")) return parseInt(id, 10);
    if (id === "single") return 1;
    const m = (/^multi-(\d+)$/).exec(id || "");
    return m ? parseInt(m[1], 10) : 1;
  };
  const cellNnodes = (cell, sel) => cell.pd ? cell.nnodes || 1 : sel.nodes !== undefined ? parseNnodes(sel.nodes) : cell.nnodes || 1;
  const PD_SERVE_PORTS = {
    prefill: 30000,
    decode: 30100
  };
  const overlayEnv = sel => overlayPart(sel, "env");
  const overlayHints = sel => overlayPart(sel, "hints");
  const renderCommand = (cell, sel, envValues, mode = "python") => {
    if (!cell) return "# No command available for the current selection.";
    const modelName = resolveModelName(sel);
    if (cell.pd && cell.commands) return interpolate(cell.commands[mode] || cell.commands.python, envValues, modelName);
    const nnodes = cellNnodes(cell, sel);
    const multinode = nnodes > 1;
    const cellEnv = [...cell.env || [], ...overlayEnv(sel)];
    const flags = overlayCompose(cell.flags, sel);
    if (multinode) {
      const PARALLELISM_ANCHORS = new Set(["--attn-dp-size", "--attention-data-parallel-size", "--dp-size", "--dp", "--tp-size", "--tp", "--sp-degree", "--ulysses-degree", "--ring-degree"]);
      let i = flags.reduce((last, flag, index) => PARALLELISM_ANCHORS.has(flag.split(/[\s=]/)[0]) ? index : last, -1);
      if (i === -1) i = flags.findIndex(f => f.startsWith("--model-path"));
      flags.splice(i + 1, 0, `--nnodes ${nnodes}`, `--node-rank {{NODE_RANK}}`, `--dist-init-addr {{NODE0_IP}}:20000`);
    }
    const pdServePort = PD_SERVE_PORTS[cell.pd ? cell.pdMode : config.resolveRecipe ? null : sel.pdMode];
    if (pdServePort !== undefined) {
      for (let j = 0; j < flags.length; j++) {
        if (flags[j].split(/[\s=]/)[0] === "--port") {
          flags[j] = `--port ${pdServePort}`;
        }
      }
    }
    let cmd;
    if (mode === "docker") {
      const di = config.dockerImages || ({});
      const image = cell.pd && cell.dockerImage || di[`${sel.hw}|${sel.variant}|${sel.quant}`] || di[`${sel.variant}|${sel.quant}`] || di[`${sel.hw}|${sel.quant}|${sel.strategy}`] || di[`${sel.hw}|${sel.quant}`] || di[sel.hw] || "lmsysorg/sglang:dev";
      const dockerRunCommand = typeof config.dockerRunCommand === "function" ? config.dockerRunCommand(sel) : config.dockerRunCommand || "sglang serve";
      const portFlag = flags.find(x => x.split(/[\s=]/)[0] === "--port");
      const servePort = portFlag ? portFlag.slice(("--port").length).trim() : "{{PORT}}";
      const hostNetwork = multinode || cell.pd || typeof config.dockerHostNetworkWhen === "function" && config.dockerHostNetworkWhen(sel, {
        flags,
        env: cellEnv
      });
      const vendorOf = hwId => {
        for (const [vendor, list] of Object.entries(HARDWARE_CATALOG)) {
          if (list.some(h => h.id === hwId)) return vendor;
        }
        const extra = (config.hardware || []).find(h => h.id === hwId);
        return extra && extra.vendor || "nvidia";
      };
      const catalogEntryOf = hwId => {
        const extra = (config.hardware || []).find(h => h.id === hwId);
        if (extra) return extra;
        for (const list of Object.values(HARDWARE_CATALOG)) {
          const hit = list.find(h => h.id === hwId);
          if (hit) return hit;
        }
        return null;
      };
      const fabricFlagsOf = hwId => (catalogEntryOf(hwId) || ({})).multiNodeDockerFlags || [];
      const davinciLines = devices => {
        const lines = [];
        for (let i = 0; i < devices; i += 4) {
          const group = [];
          for (let k = i; k < Math.min(i + 4, devices); k++) {
            group.push(`--device=/dev/davinci${k}`);
          }
          lines.push("  " + group.join(" "));
        }
        return lines;
      };
      const gpuAccessLines = vendorOf(sel.hw) === "amd" ? ["docker run", "  --device=/dev/kfd --device=/dev/dri", "  --group-add video", "  --cap-add=SYS_PTRACE --security-opt seccomp=unconfined", "  --shm-size 32g"] : vendorOf(sel.hw) === "npu" ? ["docker run --privileged --shm-size=16g", ...davinciLines((catalogEntryOf(sel.hw) || ({})).npuDevices || 16), "  --device=/dev/davinci_manager", "  --device=/dev/hisi_hdc", "  -v /usr/local/sbin:/usr/local/sbin", "  -v /usr/local/Ascend/driver:/usr/local/Ascend/driver", "  -v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware", "  -v /etc/ascend_install.info:/etc/ascend_install.info", "  -v /var/queue_schedule:/var/queue_schedule", "  -v ~/.cache/:/root/.cache/"] : ["docker run --gpus all", "  --shm-size 32g"];
      const dockerLines = [...gpuAccessLines, hostNetwork ? "  --network host" : `  -p ${servePort}:${servePort}`, ...multinode || cell.pd ? fabricFlagsOf(sel.hw).map(f => "  " + f) : [], ...vendorOf(sel.hw) === "npu" ? [] : ["  -v ~/.cache/huggingface:/root/.cache/huggingface"], ...[...config.dockerMounts || [], ...cell.pd ? cell.dockerMounts || [] : []].map(mount => `  -v ${mount}`), ...config.placeholders && config.placeholders.HF_TOKEN ? [`  --env "HF_TOKEN={{HF_TOKEN}}"`] : [], ...cellEnv.map(e => `  --env ${e}`), "  --ipc=host", `  ${image}`, `  ${dockerRunCommand}`, ...flags.map(f => "    " + f)];
      cmd = dockerLines.join(" \\\n");
    } else {
      const flagBlock = flags.map(f => "  " + f).join(" \\\n");
      const envBlock = cellEnv.length ? cellEnv.join(" \\\n") + " \\\n" : "";
      cmd = `${envBlock}sglang serve \\\n${flagBlock}`;
    }
    const hintLines = [...cell.pd ? cell.hints || [] : [], ...overlayHints(sel), ...multinode && config.multiNodeHints && config.multiNodeHints[sel.hw] ? config.multiNodeHints[sel.hw] : []];
    if (hintLines.length) {
      const hint = hintLines.map(line => line.length ? "# " + line : "#").join("\n");
      cmd = `${hint}\n${cmd}`;
    }
    cmd = interpolate(cmd, envValues, modelName);
    if (multinode) {
      const header = `# Multi-node (${nnodes} nodes). Run the same command on every node with:\n` + `#   <node-rank> = 0 on the head node, 1..${nnodes - 1} on the others\n` + `#   <node0-ip>  = IP of the head node (reachable from all others)`;
      cmd = `${header}\n${cmd}`;
    }
    return cmd;
  };
  const ACCURACY_LABELS = config.accuracyLabels || [];
  const renderBenchmarkCard = entry => {
    const pct = entry && entry.latencyPercentile || config.latencyPercentile || "P50";
    const SPEED_LABELS = [["ttft_ms", `TTFT (${pct})`, "ms"], ["tpot_ms", `TPOT (${pct})`, "ms"], ["tokens_per_sec_per_gpu", "throughput per gpu", "tok/s"], ["interactivity", "interactivity", "tokens/s/user", m => m.tpot_ms != null && m.tpot_ms !== 0 ? Math.round(1000 / m.tpot_ms * 10) / 10 : null]];
    const WORKLOAD_KEYS = ["dataset", "isl", "osl", "max_concurrency"];
    const fmt = (val, unit) => {
      if (val === null || val === undefined) return null;
      return `${val}${unit ? " " + unit : ""}`;
    };
    const formatWorkloadParts = (workload, keys) => {
      if (!workload) return "";
      const parts = [];
      if (keys.has("dataset") && workload.dataset) parts.push(workload.dataset);
      if (keys.has("isl") || keys.has("osl")) {
        if (workload.isl != null || workload.osl != null) {
          parts.push(`in/out=${workload.isl != null ? workload.isl : "?"}/${workload.osl != null ? workload.osl : "?"}`);
        }
      }
      if (keys.has("max_concurrency") && workload.max_concurrency != null) {
        parts.push(`max-concurrency=${workload.max_concurrency}`);
      }
      return parts.join(", ");
    };
    const ALWAYS_PER_COLUMN = new Set(["max_concurrency"]);
    const ATOMIC_WORKLOAD_GROUPS = [["isl", "osl"]];
    const partitionWorkload = measurements => {
      const shared = new Set();
      const differing = new Set();
      for (const k of WORKLOAD_KEYS) {
        const seen = new Set();
        let anyPresent = false;
        for (const m of measurements) {
          const v = m && m.workload ? m.workload[k] : undefined;
          if (v != null) anyPresent = true;
          seen.add(v);
        }
        if (!anyPresent) continue;
        if (ALWAYS_PER_COLUMN.has(k) || seen.size > 1) differing.add(k); else shared.add(k);
      }
      for (const group of ATOMIC_WORKLOAD_GROUPS) {
        if (!group.some(k => differing.has(k))) continue;
        for (const k of group) if (shared.delete(k)) differing.add(k);
      }
      return {
        shared,
        differing
      };
    };
    const renderBenchTable = ({title, sharedText, colHeaders, rows, colCount, legend}) => {
      if (rows.length === 0) return null;
      const showColHeaders = colHeaders.length > 0 && colHeaders.some(h => h !== "");
      return <div style={s.benchBlock}>
          <div style={s.benchBlockTitle}>{title}</div>
          {sharedText && <div style={s.benchWorkload}>{sharedText}</div>}
          {}
          <div className="sg-bench-scroll" style={s.benchTableScroll} {...colCount > 1 ? {
        tabIndex: 0,
        role: "group",
        "aria-label": sharedText ? `${title} — ${sharedText}` : title
      } : {}}>
            <div style={{
        ...s.benchTable,
        gridTemplateColumns: `max-content repeat(${colCount}, minmax(max-content, 1fr))`
      }}>
              {showColHeaders && <div key="corner" style={s.benchTableCornerHead}></div>}
              {showColHeaders && colHeaders.map((h, i) => <div key={`hdr-${i}`} style={s.benchTableHead}>{h}</div>)}
              {showColHeaders && <div key="sep" style={s.benchTableSeparator}></div>}
              {rows.map(r => [<div key={`lbl-${r.label}`} style={s.benchTableLabel}>{r.label}</div>, ...r.values.map((v, i) => <div key={`val-${r.label}-${i}`} style={v === null ? {
        ...s.benchTableValue,
        ...s.benchTableValueMissing
      } : s.benchTableValue}>
                    {v !== null ? v : "—"}
                  </div>)])}
            </div>
          </div>
          {legend && <div style={s.benchLegend}>
              {(Array.isArray(legend) ? legend : [legend]).map((line, i) => <div key={`legend-${i}`}>{line}</div>)}
            </div>}
        </div>;
    };
    const buildSpeedTable = measurements => {
      if (measurements.length === 0) return null;
      const {shared, differing} = partitionWorkload(measurements);
      const sharedText = formatWorkloadParts(measurements[0] && measurements[0].workload, shared);
      const colHeaders = measurements.map(m => formatWorkloadParts(m && m.workload, differing));
      const rows = SPEED_LABELS.map(tup => {
        const [key, label, unit, compute] = tup;
        const values = measurements.map(m => {
          const raw = compute ? compute(m) : m[key];
          return fmt(raw, unit);
        });
        return {
          label,
          values
        };
      });
      return {
        title: "Speed",
        sharedText,
        colHeaders,
        rows,
        colCount: measurements.length,
        legend: [`throughput per gpu = (input+output tokens)/elapsed/GPU`, `interactivity = 1000/TPOT(ms) (tokens/s/user)`]
      };
    };
    const buildAccuracyTable = accuracy => {
      if (!accuracy) return null;
      const rows = ACCURACY_LABELS.map(([key, label, unit]) => {
        const v = fmt(accuracy[key], unit);
        if (v === null) return null;
        return {
          label,
          values: [v]
        };
      }).filter(r => r !== null);
      if (rows.length === 0) return null;
      return {
        title: "Accuracy",
        sharedText: null,
        colHeaders: [],
        rows,
        colCount: 1
      };
    };
    const accuracy = effectiveAccuracy(entry, sel);
    const isEmpty = benchmarkIsEmpty(entry, accuracy);
    const measurements = !isEmpty ? normalizeSpeed(entry && entry.speed) : [];
    const accuracyTable = !isEmpty ? buildAccuracyTable(accuracy) : null;
    const speedTable = !isEmpty ? buildSpeedTable(measurements) : null;
    const hasBenchCmds = !isEmpty && buildBenchCommands(entry, sel) !== null;
    return <div style={s.benchCard}>
        <div style={s.benchHeader}>
          <div style={s.benchTitle}>Benchmark</div>
          <div style={s.benchHeaderRight}>
            {!isEmpty && entry && entry.sglang_version && <div style={s.benchVersion}>measured on sglang <code>{entry.sglang_version}</code></div>}
            {hasBenchCmds && <button style={s.iconButton} onClick={() => setModal("bench")}>⚡ Reproduce</button>}
          </div>
        </div>
        {isEmpty ? <div style={s.benchEmpty}>
            Benchmark data pending for this combination — submit yours via the Playground's Submit ↗ button.
          </div> : <>
            {accuracyTable && renderBenchTable(accuracyTable)}
            {speedTable && renderBenchTable(speedTable)}
            {entry && entry.notes && <div style={s.benchNotes}>{entry.notes}</div>}
          </>}
      </div>;
  };
  const buildBenchCommands = (entry, sel) => {
    const bc = config.benchmarkCommands;
    if (!bc) return null;
    const acc = effectiveAccuracy(entry, sel);
    const accuracy = [];
    if (bc.accuracy) {
      for (const [key, label] of ACCURACY_LABELS) {
        if (acc[key] == null) continue;
        const tmpl = bc.accuracy[key];
        const resolved = typeof tmpl === "string" ? tmpl : tmpl && tmpl[sel.variant] || null;
        if (resolved) accuracy.push({
          key,
          label,
          template: resolved
        });
      }
    }
    let speed = null;
    if (bc.speed && entry) {
      const ms = normalizeSpeed(entry.speed).filter(m => m && m.workload && m.workload.max_concurrency != null);
      const concurrencies = [...new Set(ms.map(m => m.workload.max_concurrency))].sort((a, b) => a - b);
      if (concurrencies.length) {
        speed = {
          template: bc.speed,
          concurrencies,
          workload: ms[0].workload,
          numPromptsOf: c => {
            const m = ms.find(x => x.workload.max_concurrency === c);
            if (m && m.workload.num_prompts != null) return m.workload.num_prompts;
            const tbl = bc.numPromptsByConc;
            if (tbl && tbl[c] != null) return tbl[c];
            return Math.max(c * 2, 200);
          }
        };
      }
    }
    if (accuracy.length === 0 && !speed) return null;
    return {
      accuracy,
      speed
    };
  };
  const buildHardwareGroups = () => {
    const supported = new Set(config.supportedHardware);
    const catalog = {};
    for (const [vendor, list] of Object.entries(HARDWARE_CATALOG)) catalog[vendor] = [...list];
    for (const hw of config.hardware || []) {
      const vendor = hw.vendor || "nvidia";
      const list = catalog[vendor] || (catalog[vendor] = []);
      const entry = {
        id: hw.id,
        label: hw.label,
        vram: hw.vram
      };
      const i = list.findIndex(x => x.id === hw.id);
      if (i >= 0) list[i] = entry; else list.push(entry);
    }
    const groups = [];
    for (const [vendor, list] of Object.entries(catalog)) {
      const items = list.filter(hw => supported.has(hw.id)).map(hw => ({
        id: hw.id,
        label: hw.label,
        subtitle: hw.vram
      }));
      if (items.length) groups.push({
        label: vendor.toUpperCase(),
        items
      });
    }
    if (config.groupHardware === false) {
      return [{
        label: null,
        items: groups.flatMap(group => group.items)
      }];
    }
    return groups;
  };
  const initialSelectionFromCells = () => {
    const first = (config.cells || [])[0];
    const sel = Object.fromEntries(DIMENSIONS.map(d => [d, first ? first.match[d] : ""]));
    for (const spec of overlayDimSpecs) {
      const opts = spec.options || [];
      sel[spec.id] = (spec.default ?? (opts[0] && opts[0].id)) ?? "";
    }
    if (!commandBuilder) return sel;
    return {
      ...sel,
      hw: commandBuilder.defaultSelection?.hw || config.supportedHardware?.[0] || "",
      ...commandBuilder.defaultSelection || ({})
    };
  };
  const normalizeBuilderSelection = parsed => {
    const out = {
      ...initialSelectionFromCells(),
      ...parsed
    };
    if (!(config.supportedHardware || []).includes(out.hw)) {
      out.hw = commandBuilder.defaultSelection?.hw || config.supportedHardware?.[0] || "";
    }
    for (const spec of overlayDimSpecs) {
      if (spec.kind === "number") {
        const value = Number.parseInt(out[spec.id], 10);
        out[spec.id] = Math.min(spec.max, Math.max(spec.min, Number.isFinite(value) ? value : Number(spec.default ?? spec.min)));
        continue;
      }
      const options = spec.options || [];
      if (!options.some(option => option.id === out[spec.id])) {
        out[spec.id] = (spec.default ?? options[0]?.id) ?? "";
      }
    }
    for (const [key, bounds] of Object.entries(commandBuilder.resource?.limits || ({}))) {
      const fallback = Number((commandBuilder.defaultSelection?.[key] ?? bounds.min) ?? 1);
      const value = Number.parseInt(out[key], 10);
      out[key] = Math.min(bounds.max, Math.max(bounds.min, Number.isFinite(value) ? value : fallback));
    }
    for (const key of ["tp_size", "ulysses_degree", "ring_degree"]) {
      const value = Number.parseInt(out[key], 10);
      out[key] = Number.isFinite(value) && value > 0 ? value : 1;
    }
    out.topology_mode = out.topology_mode === "manual" ? "manual" : "auto";
    return out;
  };
  const placeholderDefaults = schema => {
    const out = {};
    for (const [k, v] of Object.entries(schema || ({}))) out[k] = v.default ?? "";
    return out;
  };
  const [isDark, setIsDark] = useState(false);
  useEffect(() => {
    const check = () => {
      const html = document.documentElement;
      setIsDark(html.classList.contains("dark") || html.getAttribute("data-theme") === "dark" || html.style.colorScheme === "dark");
    };
    check();
    const observer = new MutationObserver(check);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class", "data-theme", "style"]
    });
    return () => observer.disconnect();
  }, []);
  const STORAGE_KEY = "sglang-deploy-env";
  const [env, setEnv] = useState(() => placeholderDefaults(config.placeholders));
  useEffect(() => {
    try {
      const raw = window.localStorage.getItem(STORAGE_KEY);
      if (raw) {
        const parsed = JSON.parse(raw);
        setEnv({
          ...placeholderDefaults(config.placeholders),
          ...parsed
        });
      }
    } catch {}
  }, []);
  const saveEnv = next => {
    setEnv(next);
    try {
      window.localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
    } catch {}
  };
  const [sel, setSel] = useState(() => initialSelectionFromCells());
  const [selectionHydrated, setSelectionHydrated] = useState(false);
  const INTERNAL_HASH_STATE_KEY = "__sglangDeployInternalHash";
  const DEPLOYMENT_COMPONENT_ID = "deployment-configurator";
  useEffect(() => {
    const hydrate = () => {
      const raw = window.location.hash.replace(/^#/, "");
      if (!raw) return;
      const params = new URLSearchParams(raw);
      const initial = initialSelectionFromCells();
      const parsed = {
        ...initial
      };
      let touched = false;
      params.forEach((value, key) => {
        if ((key in parsed)) {
          parsed[key] = value;
          touched = true;
        }
      });
      if (!touched) return;
      setSel(commandBuilder ? normalizeBuilderSelection(parsed) : validateSelection(config.cells, parsed));
      const historyState = window.history.state;
      const isInternalHash = historyState && typeof historyState === "object" && historyState[INTERNAL_HASH_STATE_KEY] === `#${raw}`;
      if (isInternalHash) return;
      const el = document.getElementById(DEPLOYMENT_COMPONENT_ID);
      if (el) el.scrollIntoView({
        behavior: "smooth",
        block: "start"
      });
    };
    hydrate();
    setSelectionHydrated(true);
    window.addEventListener("hashchange", hydrate);
    return () => window.removeEventListener("hashchange", hydrate);
  }, []);
  useEffect(() => {
    if (!selectionHydrated) return;
    const target = "#" + new URLSearchParams(sel).toString();
    if (window.location.hash !== target) {
      const historyState = window.history.state && typeof window.history.state === "object" ? window.history.state : {};
      window.history.replaceState({
        ...historyState,
        [INTERNAL_HASH_STATE_KEY]: target
      }, "", target);
    }
    window.dispatchEvent(new CustomEvent("sglang-deploy-sel", {
      detail: sel
    }));
  }, [sel, selectionHydrated]);
  const [modal, setModal] = useState(null);
  useEffect(() => {
    if (modal === null) return;
    const onKey = e => {
      if (e.key === "Escape") setModal(null);
    };
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    window.addEventListener("keydown", onKey);
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = prev;
    };
  }, [modal]);
  const [copied, setCopied] = useState(false);
  const [curlCopied, setCurlCopied] = useState(false);
  const [envDraft, setEnvDraft] = useState(env);
  const [benchConc, setBenchConc] = useState(null);
  const [benchAcc, setBenchAcc] = useState(null);
  const [benchCopied, setBenchCopied] = useState(null);
  const configuredRunModes = typeof config.runModes === "function" ? config.runModes(sel) : config.runModes;
  const runModes = configuredRunModes || ["python", "docker"];
  const [runMode, setRunMode] = useState(runModes[0]);
  const [builderScope, setBuilderScope] = useState("base");
  const [builderServerSetting, setBuilderServerSetting] = useState(null);
  const [builderAdvanced, setBuilderAdvanced] = useState(false);
  const [serveExpanded, setServeExpanded] = useState(false);
  const [requestExpanded, setRequestExpanded] = useState(false);
  const [builderHeadAddress, setBuilderHeadAddress] = useState("<head-node-ip>");
  const [builderNodeRank, setBuilderNodeRank] = useState(0);
  const [blockedNote, setBlockedNote] = useState(null);
  const flashBlockedNote = (dim, reason) => {
    const note = {
      dim,
      reason
    };
    setBlockedNote(note);
    setTimeout(() => setBlockedNote(cur => cur === note ? null : cur), 4000);
  };
  useEffect(() => {
    if (builderNodeRank >= Number(sel.nodes || 1)) setBuilderNodeRank(0);
  }, [sel.nodes, builderNodeRank]);
  const hasRunMode = runModes.includes(runMode);
  const fallbackRunMode = runModes[0];
  const activeRunMode = hasRunMode ? runMode : fallbackRunMode;
  useEffect(() => {
    if (!hasRunMode) setRunMode(fallbackRunMode);
  }, [hasRunMode, fallbackRunMode]);
  useEffect(() => {
    if (modal === "env") setEnvDraft(env);
  }, [modal, env]);
  const [mambaRatio, setMambaRatio] = useState(null);
  useEffect(() => {
    const onRatio = e => setMambaRatio(e.detail && (e.detail.baseRatio || e.detail.ratio) || null);
    window.addEventListener("sglang-k3-mamba-ratio", onRatio);
    return () => window.removeEventListener("sglang-k3-mamba-ratio", onRatio);
  }, []);
  const s = makeStyles(isDark);
  const cell = commandBuilder ? commandBuilder.resolveDeployment(sel) : findCell(config.cells, sel);
  const builderMeta = cell && cell.builder || ({});
  const verifyStatus = cellVerifyStatus(cell, sel);
  const cellWithRatio = (() => {
    if (!cell || !mambaRatio) return cell;
    if (cell.flags.some(f => f.startsWith("--mamba-full-memory-ratio") || f.startsWith("--max-mamba-cache-size"))) return cell;
    const flags = [...cell.flags];
    const line = `--mamba-full-memory-ratio ${mambaRatio}`;
    const i = flags.findIndex(f => f.startsWith("--host"));
    if (i >= 0) flags.splice(i, 0, line); else flags.push(line);
    return {
      ...cell,
      flags
    };
  })();
  const commandEnv = commandBuilder ? {
    ...env,
    NODE_RANK: String(builderNodeRank),
    NODE0_IP: builderHeadAddress || "<head-node-ip>"
  } : env;
  const command = renderCommand(cellWithRatio, sel, commandEnv, activeRunMode);
  const effFlags = cell ? overlayCompose(cell.flags, sel) : [];
  const specAlgoFlag = effFlags.find(f => f.split(/[\s=]/)[0] === "--speculative-algorithm");
  const specMrrFlag = effFlags.find(f => f.split(/[\s=]/)[0] === "--max-running-requests");
  const mtpHint = !!specAlgoFlag && !specMrrFlag;
  const specPinnedHint = !!specAlgoFlag && !!specMrrFlag;
  const specMrrValue = specMrrFlag ? specMrrFlag.split(/[\s=]/).filter(Boolean)[1] || "" : "";
  const SPEC_ALGO_LABEL = {
    EAGLE: "MTP",
    EAGLE3: "MTP",
    FROZEN_KV_MTP: "MTP",
    DSPARK: "DSpark",
    DFLASH: "DFlash",
    NGRAM: "N-gram",
    STANDALONE: "standalone draft"
  };
  const specAlgoName = (() => {
    if (!specAlgoFlag) return "MTP";
    const v = specAlgoFlag.split(/[\s=]/).filter(Boolean)[1] || "";
    return SPEC_ALGO_LABEL[v.toUpperCase()] || v || "MTP";
  })();
  const renderWarn = text => {
    const out = [];
    const re = /\[([^\]]+)\]\(#([^)]+)\)/g;
    let last = 0;
    for (let m; m = re.exec(text); last = m.index + m[0].length) {
      if (m.index > last) out.push(text.slice(last, m.index));
      const anchor = m[2];
      out.push(<button key={m.index} type="button" onClick={() => {
        const el = document.getElementById(anchor);
        if (el) el.scrollIntoView({
          behavior: "smooth",
          block: "start"
        });
      }} style={{
        background: "transparent",
        border: "none",
        padding: 0,
        color: isDark ? "#FDBA74" : "#C2410C",
        cursor: "pointer",
        font: "inherit",
        fontWeight: 600,
        textDecoration: "underline",
        textUnderlineOffset: "2px"
      }}>
          {m[1]}
        </button>);
    }
    if (last < text.length) out.push(text.slice(last));
    return out;
  };
  const modelName = resolveModelName(sel);
  const curlTemplate = typeof config.curl === "function" ? config.curl(sel, cell) : config.curl;
  const curlText = interpolate(curlTemplate || "", cell && cell.pd && cell.router ? {
    ...env,
    CURL_PORT: String(cell.router.port)
  } : env, modelName);
  const hwGroups = buildHardwareGroups();
  const benchEntry = benchmarks ? findBenchmark(benchmarks, sel) : null;
  const isOverlayDim = dim => overlayDimSpecs.some(d => d.id === dim);
  const findOption = (dim, value) => {
    const spec = [...matchDimSpecs, ...overlayDimSpecs].find(d => d.id === dim);
    return spec && (spec.options || []).find(o => o.id === value);
  };
  const isEnabled = (dim, value) => {
    const opt = findOption(dim, value);
    if (opt && optionDisabled(opt, sel)) return false;
    if (commandBuilder && dim === "hw") return true;
    return isOverlayDim(dim) || isOptionAvailable(config.cells || [], sel, dim, value);
  };
  const reseatHiddenPicks = next => {
    let out = next;
    for (const spec of [...matchDimSpecs, ...overlayDimSpecs]) {
      const opts = visibleOptions(spec, out).filter(o => !optionDisabled(o, out));
      if (!opts.length) continue;
      if (!opts.some(o => o.id === out[spec.id])) {
        out = {
          ...out,
          [spec.id]: opts[0].id
        };
      }
    }
    return out;
  };
  const recommendedBuilderRecipe = hw => {
    const recipes = commandBuilder.resource?.verifiedRecipes || [];
    return recipes.find(entry => entry.hw === hw && entry.default) || recipes.find(entry => entry.hw === hw);
  };
  const handleSelect = (dim, value) => {
    if (commandBuilder) {
      setSel(prev => {
        let next = {
          ...prev,
          [dim]: value
        };
        if (dim === "hw") {
          const currentRecipe = recommendedBuilderRecipe(prev.hw);
          const nextRecipe = recommendedBuilderRecipe(value);
          const resourcesFollowPlatformDefault = !!currentRecipe && Number(prev.nodes) === Number(currentRecipe.nodes) && Number(prev.gpus_per_node) === Number(currentRecipe.gpus_per_node);
          next = {
            ...next,
            nodes: resourcesFollowPlatformDefault ? nextRecipe?.nodes ?? next.nodes : next.nodes,
            gpus_per_node: resourcesFollowPlatformDefault ? nextRecipe?.gpus_per_node ?? next.gpus_per_node : next.gpus_per_node,
            topology_mode: "auto",
            tp_size: resourcesFollowPlatformDefault ? nextRecipe?.tp_size ?? 1 : next.tp_size,
            ulysses_degree: resourcesFollowPlatformDefault ? nextRecipe?.ulysses_degree ?? 1 : next.ulysses_degree,
            ring_degree: resourcesFollowPlatformDefault ? nextRecipe?.ring_degree ?? 1 : next.ring_degree,
            placement: resourcesFollowPlatformDefault ? nextRecipe?.placement || "auto" : next.placement,
            encoder: resourcesFollowPlatformDefault ? nextRecipe?.encoder || "auto" : next.encoder
          };
        }
        return reseatHiddenPicks(normalizeBuilderSelection(next));
      });
      return;
    }
    setSel(prev => reseatHiddenPicks(isOverlayDim(dim) ? {
      ...prev,
      [dim]: value
    } : snapToValidCell(config.cells, prev, dim, value)));
  };
  const commitBuilderNumber = (event, currentValue, bounds, commit) => {
    const parsed = Number(event.currentTarget.value);
    if (!Number.isInteger(parsed)) {
      event.currentTarget.value = String(currentValue);
      return;
    }
    const value = Math.min(bounds.max, Math.max(bounds.min, parsed));
    event.currentTarget.value = String(value);
    commit(value);
  };
  const renderBuilderNumberInput = ({identity, value, min, max, label, onCommit}) => <input key={identity} type="number" inputMode="numeric" min={min} max={max} step="1" defaultValue={value} aria-label={label} onFocus={event => event.currentTarget.select()} onBlur={event => commitBuilderNumber(event, value, {
    min,
    max
  }, onCommit)} onKeyDown={event => {
    if (event.key === "Enter") event.currentTarget.blur();
  }} />;
  const updateBuilderResource = (key, delta) => {
    if (!commandBuilder) return;
    const bounds = commandBuilder.resource?.limits?.[key] || ({
      min: 1,
      max: 8
    });
    setSel(prev => {
      const value = Math.min(bounds.max, Math.max(bounds.min, Number(prev[key]) + delta));
      return normalizeBuilderSelection({
        ...prev,
        [key]: value,
        topology_mode: "auto"
      });
    });
  };
  const setBuilderResource = (key, rawValue) => {
    if (!commandBuilder) return;
    const value = Number.parseInt(rawValue, 10);
    if (!Number.isFinite(value)) return;
    const bounds = commandBuilder.resource?.limits?.[key] || ({
      min: 1,
      max: 8
    });
    setSel(prev => normalizeBuilderSelection({
      ...prev,
      [key]: Math.min(bounds.max, Math.max(bounds.min, value)),
      topology_mode: "auto"
    }));
  };
  const editBuilderTopology = (key, value) => {
    if (!commandBuilder) return;
    setSel(prev => normalizeBuilderSelection({
      ...prev,
      topology_mode: "manual",
      [key]: Number.parseInt(value, 10) || 1
    }));
  };
  const handleCopy = () => {
    navigator.clipboard.writeText(command);
    setCopied(true);
    setTimeout(() => setCopied(false), 1200);
  };
  const copyCurl = () => {
    navigator.clipboard.writeText(curlText);
    setCurlCopied(true);
    setTimeout(() => setCurlCopied(false), 1200);
  };
  const copyBench = (key, text) => {
    navigator.clipboard.writeText(text);
    setBenchCopied(key);
    setTimeout(() => setBenchCopied(null), 1200);
  };
  const placeholderGroups = (() => {
    const out = {
      command: [],
      curl: []
    };
    for (const [key, meta] of Object.entries(config.placeholders || ({}))) {
      (out[meta.target] || (out[meta.target] = [])).push({
        key,
        ...meta
      });
    }
    return out;
  })();
  const renderButton = (item, dim, selectedId) => {
    const checked = selectedId === item.id;
    const disabled = !isEnabled(dim, item.id);
    return <label key={item.id} className="sg-command-visualizer-choice" role="radio" aria-checked={checked} aria-disabled={disabled} tabIndex={disabled ? -1 : 0} style={{
      ...s.labelBase,
      ...checked ? s.checked : {},
      ...disabled ? s.disabled : {}
    }} title={disabled ? (typeof item.disableReason === "function" ? item.disableReason(sel) : item.disableReason) || "Not supported for current selection" : ""} onClick={e => {
      if (disabled) {
        e.preventDefault();
        return;
      }
      handleSelect(dim, item.id);
    }} onKeyDown={e => {
      if (disabled || e.key !== "Enter" && e.key !== " ") return;
      e.preventDefault();
      handleSelect(dim, item.id);
    }}>
        <input type="radio" checked={checked} disabled={disabled} readOnly style={{
      display: "none"
    }} />
        <span>{item.label}</span>
        {item.subtitle && <small style={{
      ...s.subtitle,
      color: checked ? "rgba(255,255,255,0.85)" : "inherit"
    }}>
            {item.subtitle}
          </small>}
      </label>;
  };
  const renderFlatSection = (title, options, dim, selectedId) => <div style={s.card}>
      <div style={s.title}>{title}</div>
      <div style={s.itemsGrid(options.length)}>
        {options.map(item => renderButton(item, dim, selectedId))}
      </div>
    </div>;
  const maxHwCols = Math.max(...hwGroups.map(x => x.items.length));
  if (commandBuilder) {
    const scopeLabel = {
      base: "Setup",
      serve: "Server",
      request: "Request"
    };
    const scopedDims = scope => overlayDimSpecs.filter(dim => {
      if ((dim.scope || "base") !== scope) return false;
      if (dim.kind === "number") {
        return typeof dim.showWhen !== "function" || dim.showWhen(sel);
      }
      return rowVisible(dim, sel);
    });
    const baseDims = scopedDims("base");
    const serveDims = scopedDims("serve");
    const requestDims = scopedDims("request");
    const errors = builderMeta.errors || [];
    const warnings = builderMeta.warnings || [];
    const invalid = errors.length > 0;
    const totalGpus = Number(sel.nodes) * Number(sel.gpus_per_node);
    const topology = builderMeta.topology || ({});
    const verification = builderMeta.verification || ({});
    const scopeIsVerified = scope => scopedDims(scope).every(dim => {
      const option = (dim.options || []).find(entry => entry.id === sel[dim.id]);
      if (option && optionSoft(option, sel)) return false;
      const predicate = option?.verifiedWhen ?? dim.verifiedWhen;
      return typeof predicate === "function" ? !!predicate(sel) : predicate !== false;
    });
    const serveStatus = invalid ? "error" : scopeIsVerified("serve") ? verification.serve || verifyStatus : "unverified";
    const requestStatus = invalid ? "error" : scopeIsVerified("request") ? verification.request || verifyStatus : "unverified";
    const statusText = status => ({
      verified: "Verified",
      unverified: "Unverified",
      "in-progress": "Verification in progress",
      error: "Invalid configuration"
    })[status] || "Unverified";
    const activeServerSetting = serveDims.find(dim => dim.id === builderServerSetting) || serveDims[0];
    const selectedOption = dim => (dim.options || []).find(option => option.id === sel[dim.id]);
    const effectiveSetting = dim => builderMeta.resolvedSettings?.[dim.id] || selectedOption(dim)?.label || sel[dim.id] || "—";
    const recommendedRecipe = recommendedBuilderRecipe(sel.hw);
    const recommendedIsVerified = !!recommendedRecipe && !recommendedRecipe.unverified && (typeof recommendedRecipe.verifiedWhen !== "function" || recommendedRecipe.verifiedWhen(sel));
    const recommendedInUse = !!recommendedRecipe && Number(sel.nodes) === recommendedRecipe.nodes && Number(sel.gpus_per_node) === recommendedRecipe.gpus_per_node && sel.topology_mode === "auto" && serveDims.every(dim => {
      const expected = recommendedRecipe[dim.id] ?? dim.default;
      if (dim.id === "attention") return sel.attention === "platform";
      return expected === undefined || sel[dim.id] === expected || ["placement", "encoder"].includes(dim.id) && sel[dim.id] === "auto";
    });
    const restoreRecommendedRecipe = () => {
      if (!recommendedRecipe) return;
      setSel(prev => reseatHiddenPicks(normalizeBuilderSelection({
        ...prev,
        ...Object.fromEntries(serveDims.map(dim => [dim.id, (recommendedRecipe[dim.id] ?? dim.default) ?? dim.options?.[0]?.id])),
        nodes: recommendedRecipe.nodes,
        gpus_per_node: recommendedRecipe.gpus_per_node,
        topology_mode: "auto",
        tp_size: recommendedRecipe.tp_size,
        ulysses_degree: recommendedRecipe.ulysses_degree,
        ring_degree: recommendedRecipe.ring_degree,
        placement: recommendedRecipe.placement || "auto",
        attention: "platform",
        precision: "native",
        encoder: recommendedRecipe.encoder || "auto",
        execution: recommendedRecipe.execution || "eager"
      })));
    };
    const renderBuilderChoice = (item, dim) => {
      const checked = sel[dim.id] === item.id;
      const disabled = !isEnabled(dim.id, item.id);
      const soft = !disabled && optionSoft(item, sel);
      const reason = disabled ? item.disableReason || "Not available for this configuration" : soft ? item.softReason || "Runs, but this combination is not a verified recipe yet." : "";
      return <button key={item.id} type="button" className="sgd-builder-choice" data-selected={checked ? "true" : "false"} data-blocked={disabled ? "true" : undefined} data-soft={soft ? "true" : undefined} aria-disabled={disabled} aria-pressed={checked} title={reason} onClick={() => {
        if (disabled) {
          flashBlockedNote(dim.id, reason);
          return;
        }
        handleSelect(dim.id, item.id);
      }}>
          <span className="sgd-builder-choice-dot" aria-hidden="true" />
          <span>{item.label}</span>
          {item.subtitle && <small>{item.subtitle}</small>}
        </button>;
    };
    const renderBuilderDimension = dim => <section className="sgd-builder-section" key={dim.id}>
        <div className="sgd-builder-section-heading">
          <span>{dim.title}</span>
          {dim.description && <small>{dim.description}</small>}
        </div>
        <div className="sgd-builder-choice-grid" data-density={(dim.options || []).length > 5 ? "compact" : "normal"}>
          {visibleOptions(dim, sel).map(option => renderBuilderChoice(option, dim))}
        </div>
        {blockedNote && blockedNote.dim === dim.id && <p className="sgd-builder-blocked-note" role="status">{blockedNote.reason}</p>}
      </section>;
    const renderStepper = (key, label, detail) => {
      const bounds = commandBuilder.resource?.limits?.[key] || ({
        min: 1,
        max: 8
      });
      return <div className="sgd-builder-stepper-field">
          <div>
            <span>{label}</span>
            {detail && <small>{detail}</small>}
          </div>
          <div className="sgd-builder-stepper" aria-label={label}>
            <button type="button" aria-label={`Decrease ${label}`} disabled={Number(sel[key]) <= bounds.min} onClick={() => updateBuilderResource(key, -1)}>−</button>
            {renderBuilderNumberInput({
        identity: `${key}-${sel[key]}`,
        value: sel[key],
        min: bounds.min,
        max: bounds.max,
        label,
        onCommit: value => setBuilderResource(key, value)
      })}
            <button type="button" aria-label={`Increase ${label}`} disabled={Number(sel[key]) >= bounds.max} onClick={() => updateBuilderResource(key, 1)}>+</button>
          </div>
        </div>;
    };
    const renderBaseScope = () => <div className="sgd-builder-scope-panel" data-scope="base">
        {recommendedRecipe && <section className="sgd-builder-recipe">
            <div>
              {}
              <span>{recommendedIsVerified ? "Verified recipe" : "Derived recipe"} · {sel.hw.toUpperCase()}</span>
              <strong>
                {[`${recommendedRecipe.nodes * recommendedRecipe.gpus_per_node} GPUs`, recommendedRecipe.tp_size > 1 && `TP ${recommendedRecipe.tp_size}`, `Ulysses ${recommendedRecipe.ulysses_degree}`, recommendedRecipe.ring_degree > 1 && `Ring ${recommendedRecipe.ring_degree}`, ({
      resident: "Resident",
      fsdp: "FSDP",
      offload: "Layerwise offload"
    })[recommendedRecipe.placement]].filter(Boolean).join(" · ")}
              </strong>
            </div>
            <div>
              {renderStatus(recommendedIsVerified ? "verified" : "unverified")}
              {recommendedInUse ? <small>In use</small> : <button type="button" className="sgd-builder-text-action" onClick={restoreRecommendedRecipe}>{recommendedIsVerified ? "Use verified recipe" : "Use derived recipe"}</button>}
            </div>
          </section>}
        <section className="sgd-builder-section">
          <div className="sgd-builder-section-heading"><span>Hardware</span></div>
          <div className="sgd-builder-hardware-grid">
            {hwGroups.flatMap(group => group.items).map(item => {
      const selected = sel.hw === item.id;
      return <button key={item.id} type="button" className="sgd-builder-hardware" data-selected={selected ? "true" : "false"} aria-pressed={selected} onClick={() => handleSelect("hw", item.id)}>
                  <span className="sgd-builder-choice-dot" aria-hidden="true" />
                  <strong>{item.label}</strong>
                  <small>{item.subtitle}</small>
                </button>;
    })}
          </div>
        </section>

        {}
        <section className="sgd-builder-section">
          <div className="sgd-builder-section-heading">
            <span>Resources</span>
            <small>{builderMeta.topologySummary || "No valid topology"}</small>
          </div>
          <div className="sgd-builder-resource-grid">
            {renderStepper("nodes", "Nodes")}
            {renderStepper("gpus_per_node", "GPUs / node")}
          </div>
          {Number(sel.nodes) > 1 && <p className="sgd-builder-resource-summary">
              {sel.nodes} nodes × {sel.gpus_per_node} {sel.hw.toUpperCase()} = {totalGpus} GPUs
            </p>}
          <button type="button" className="sgd-builder-text-action sgd-builder-topology-toggle" aria-expanded={builderAdvanced} onClick={() => setBuilderAdvanced(open => !open)}>
            Advanced topology <span aria-hidden="true">{builderAdvanced ? "↗" : "↘"}</span>
          </button>
          {builderAdvanced && <div className="sgd-builder-advanced">
              <p>Auto uses an exact verified recipe when one exists; manual values are allowed when the model constraints remain valid.</p>
              <div className="sgd-builder-topology-inputs">
                {[["tp_size", "Tensor parallel", [1, 2, 4, 8]], ["ulysses_degree", "Ulysses", [1, 2, 4, 8, 16]], ["ring_degree", "Ring", [1, 2, 4, 8]]].map(([key, label, values]) => <label key={key}>
                    <span>{label}</span>
                    <select value={sel.topology_mode === "manual" ? sel[key] : topology[key] || 1} onChange={event => editBuilderTopology(key, event.target.value)}>
                      {values.map(value => <option value={value} key={value}>{value}</option>)}
                    </select>
                  </label>)}
              </div>
              <button type="button" className="sgd-builder-text-action" disabled={sel.topology_mode === "auto"} onClick={() => setSel(prev => normalizeBuilderSelection({
      ...prev,
      topology_mode: "auto"
    }))}>Use automatic topology</button>
            </div>}
          {(errors.length > 0 || warnings.length > 0) && <div className="sgd-builder-messages" data-state={errors.length ? "error" : "warning"}>
              {(errors.length ? errors : warnings).map((message, index) => <p key={index}>{message}</p>)}
            </div>}
        </section>

        {baseDims.map(renderBuilderDimension)}
      </div>;
    const renderSettingEditor = (dim, className = "", direct = false) => {
      if (!dim) return null;
      const options = visibleOptions(dim, sel);
      const currentOption = selectedOption(dim);
      return <section className={["sgd-builder-context", className].filter(Boolean).join(" ")} aria-live={direct ? undefined : "polite"}>
          <div className="sgd-builder-context-heading">
            <div>
              <span>{direct ? dim.title : `${dim.title} options`}</span>
              {dim.description && <p>{dim.description}</p>}
            </div>
            {dim.quality && <small>{dim.quality}</small>}
          </div>
          {dim.kind === "number" ? <div className="sgd-builder-request-stepper">
              <button type="button" aria-label={`Decrease ${dim.title}`} disabled={Number(sel[dim.id]) <= dim.min} onClick={() => setSel(prev => ({
        ...prev,
        [dim.id]: Math.max(dim.min, Number(prev[dim.id]) - 1)
      }))}>−</button>
              {renderBuilderNumberInput({
        identity: `${dim.id}-${sel[dim.id]}`,
        value: sel[dim.id],
        min: dim.min,
        max: dim.max,
        label: dim.title,
        onCommit: value => setSel(prev => ({
          ...prev,
          [dim.id]: value
        }))
      })}
              <button type="button" aria-label={`Increase ${dim.title}`} disabled={Number(sel[dim.id]) >= dim.max} onClick={() => setSel(prev => ({
        ...prev,
        [dim.id]: Math.min(dim.max, Number(prev[dim.id]) + 1)
      }))}>+</button>
              <span>{dim.unit || "outputs"}</span>
            </div> : <div className="sgd-builder-context-options">
              {options.map(option => renderBuilderChoice(option, dim))}
            </div>}
          {blockedNote && blockedNote.dim === dim.id && <p className="sgd-builder-blocked-note" role="status">{blockedNote.reason}</p>}
          {(currentOption?.description || dim.learnMore) && <div className="sgd-builder-context-note">
              {currentOption?.description && <p>{currentOption.description}</p>}
              {}
              {dim.learnMore && <a href={dim.learnMore}>
                  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" aria-hidden="true"><line x1="4" y1="6" x2="20" y2="6" /><line x1="4" y1="12" x2="16" y2="12" /><line x1="4" y1="18" x2="11" y2="18" /></svg>
                  Learn more
                </a>}
              {dim.docsHref && <a href={dim.docsHref}>
                  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" /><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" /></svg>
                  SGLang docs
                </a>}
            </div>}
        </section>;
    };
    const renderServerScope = () => <div className="sgd-builder-scope-panel" data-scope="serve">
        <div className="sgd-builder-setting-layout">
          <div className="sgd-builder-setting-list">
            {serveDims.map(dim => {
      const isActive = dim.id === activeServerSetting?.id;
      const option = selectedOption(dim);
      const recommended = typeof option?.recommendedWhen === "function" ? option.recommendedWhen(sel) : !!option?.recommended;
      return <div className="sgd-builder-setting-item" key={dim.id}>
                  <button type="button" className="sgd-builder-setting-row" data-active={isActive ? "true" : "false"} aria-expanded={isActive} onClick={() => setBuilderServerSetting(dim.id)}>
                    <span>{dim.title}</span>
                    <strong>{effectiveSetting(dim)}</strong>
                    {recommended && <small>Recommended</small>}
                    <span aria-hidden="true">{isActive ? "⌄" : "›"}</span>
                  </button>
                  {isActive && renderSettingEditor(dim, "sgd-builder-context--inline")}
                </div>;
    })}
          </div>
          {renderSettingEditor(activeServerSetting, "sgd-builder-context--rail")}
        </div>
      </div>;
    const renderRequestScope = () => <div className="sgd-builder-scope-panel sgd-builder-request-direct" data-scope="request">
        {requestDims.map(dim => <div className="sgd-builder-request-setting" key={dim.id}>
            {renderSettingEditor(dim, "", true)}
          </div>)}
      </div>;
    const renderScopeControls = () => {
      if (builderScope === "base") return renderBaseScope();
      if (builderScope === "serve") return renderServerScope();
      return renderRequestScope();
    };
    const renderStatus = status => <span className="sgd-builder-status" data-status={status}>
        <span aria-hidden="true" />{statusText(status)}
      </span>;
    const renderOutputCard = type => {
      const serve = type === "serve";
      const text = serve ? command : curlText;
      const canExpand = text.split("\n").length > 9;
      const expanded = serve ? serveExpanded : requestExpanded;
      const setExpanded = serve ? setServeExpanded : setRequestExpanded;
      const status = serve ? serveStatus : requestStatus;
      const emphasized = builderScope === "base" || builderScope === type;
      return <section className="sgd-builder-output" data-output={type} data-emphasized={emphasized ? "true" : "false"}>
          <header>
            <div className="sgd-builder-output-index">{serve ? "1" : "2"}</div>
            <div className="sgd-builder-output-title">
              <strong>{serve ? "Serve" : "Request"}</strong>
              <span>
                {serve ? `${sel.hw.toUpperCase()} · ${activeRunMode === "docker" ? "Docker" : "Python"}` : "cURL"}
              </span>
            </div>
            {renderStatus(status)}
          </header>
          {serve && runModes.length > 1 && <div className="sgd-builder-output-tabs" role="tablist" aria-label="Serve command format">
              {runModes.map(mode => <button type="button" role="tab" aria-selected={activeRunMode === mode} data-selected={activeRunMode === mode ? "true" : "false"} key={mode} onClick={() => setRunMode(mode)}>{mode === "docker" ? "Docker" : "Python"}</button>)}
            </div>}
          {serve && Number(sel.nodes) > 1 && <div className="sgd-builder-node-fields">
              <label>
                <span>Head address</span>
                <input value={builderHeadAddress} onChange={event => setBuilderHeadAddress(event.target.value)} />
              </label>
              <label>
                <span>Node rank</span>
                {renderBuilderNumberInput({
        identity: `node-rank-${builderNodeRank}-${sel.nodes}`,
        value: builderNodeRank,
        min: 0,
        max: Number(sel.nodes) - 1,
        label: "Node rank",
        onCommit: setBuilderNodeRank
      })}
              </label>
            </div>}
          <div className="sgd-builder-code">
            <pre className={expanded ? "is-expanded" : ""}><code>{text}</code></pre>
            <button type="button" className="sgd-builder-copy" disabled={invalid} aria-label={(serve ? copied : curlCopied) ? "Copied" : "Copy command"} data-copied={(serve ? copied : curlCopied) ? "true" : undefined} onClick={serve ? handleCopy : copyCurl}>
              <svg className="sgd-builder-copy-glyph" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><rect x="9" y="9" width="12" height="12" rx="2.5" /><path d="M15 5v-.25A2.75 2.75 0 0 0 12.25 2h-7.5A2.75 2.75 0 0 0 2 4.75v7.5A2.75 2.75 0 0 0 4.75 15H5" /></svg>
              <svg className="sgd-builder-copy-check" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5" /></svg>
            </button>
          </div>
          {invalid && <div className="sgd-builder-output-error">{errors[0]}</div>}
          <footer>
            {canExpand && <button type="button" className="sgd-builder-text-action" onClick={() => setExpanded(!expanded)}>
                {expanded ? "Collapse" : "Expand"}
              </button>}
            <div>
              <button type="button" className="sgd-builder-text-action" onClick={() => setModal("env")}>Variables</button>
            </div>
          </footer>
        </section>;
    };
    return <section id={DEPLOYMENT_COMPONENT_ID} className="not-prose sg-command-visualizer sgd-command-builder" style={{
      scrollMarginTop: "104px"
    }} aria-label={`${config.modelName} command builder`}>
        <nav className="sgd-builder-scope-tabs" role="tablist" aria-label="Command builder scope">
          {["base", "serve", "request"].map(scope => <button type="button" role="tab" key={scope} aria-label={scopeLabel[scope]} aria-selected={builderScope === scope} aria-controls={`${DEPLOYMENT_COMPONENT_ID}-controls`} data-active={builderScope === scope ? "true" : "false"} onClick={() => setBuilderScope(scope)}>
              {scopeLabel[scope]}
            </button>)}
        </nav>

        <div className="sgd-builder-main" data-scope={builderScope}>
          <div id={`${DEPLOYMENT_COMPONENT_ID}-controls`} className="sgd-builder-controls" role="tabpanel" aria-label={`${scopeLabel[builderScope]} settings`}>
            {renderScopeControls()}
          </div>
          <div className="sgd-builder-output-rail">
            {builderScope !== "request" && renderOutputCard("serve")}
            {builderScope !== "serve" && renderOutputCard("request")}
          </div>
        </div>

        {builderScope === "serve" && <p className="sgd-builder-docs-tip">
            <strong>Tip:</strong> For more server options, see the{" "}
            <a href="/docs/sglang-diffusion/api/cli">CLI reference</a>.
          </p>}

        {modal === "env" && <div style={s.modalBackdrop} onClick={() => setModal(null)}>
            <div style={s.modalBox} onClick={event => event.stopPropagation()}>
              <div style={s.modalHeader}>
                <div style={s.modalTitle}>Command variables</div>
                <button style={s.modalCloseBtn} onClick={() => setModal(null)} aria-label="Close">×</button>
              </div>
              {["command", "curl"].map(target => placeholderGroups[target].length > 0 && <div key={target}>
                  <div style={s.sectionHeading}>{target === "command" ? "Serve" : "Request"}</div>
                  {placeholderGroups[target].map(({key, label}) => <div key={key} style={s.formField}>
                      <label style={s.formLabel}>{label}</label>
                      <input style={s.formInput} value={envDraft[key] ?? ""} onChange={event => setEnvDraft({
      ...envDraft,
      [key]: event.target.value
    })} />
                    </div>)}
                </div>)}
              <div style={{
      display: "flex",
      justifyContent: "flex-end",
      gap: 8,
      marginTop: 16
    }}>
                <button style={{
      ...s.iconButton,
      padding: "6px 14px"
    }} onClick={() => setModal(null)}>Cancel</button>
                <button style={s.primaryBtn} onClick={() => {
      saveEnv(envDraft);
      setModal(null);
    }}>Save</button>
              </div>
            </div>
          </div>}
      </section>;
  }
  return <div id={DEPLOYMENT_COMPONENT_ID} style={{
    ...s.container,
    scrollMarginTop: "104px"
  }} className="not-prose sg-command-visualizer">
      {}
      <div style={s.cardColumn}>
        <div style={{
    ...s.title,
    marginBottom: "2px"
  }}>Hardware Platform</div>
        {hwGroups.map(g => <div key={g.label || "hardware"} style={s.vendorRow}>
            {g.label && <div style={s.vendorLabel}>{g.label}</div>}
            <div style={s.itemsGrid(maxHwCols)}>
              {g.items.map(item => renderButton(item, "hw", sel.hw))}
              {Array.from({
    length: maxHwCols - g.items.length
  }).map((_, i) => <div key={`pad-${i}`} />)}
            </div>
          </div>)}
      </div>

      {matchDimSpecs.filter(d => rowVisible(d, sel)).map(d => <div key={d.id}>
            {renderFlatSection(d.title, visibleOptions(d, sel), d.id, sel[d.id])}
          </div>)}
      {overlayDimSpecs.filter(d => rowVisible(d, sel)).map(d => <div key={d.id}>
            {renderFlatSection(d.title, visibleOptions(d, sel), d.id, sel[d.id])}
          </div>)}

      {}
      <div style={s.card}>
        <div style={s.title}>Command:</div>
        <div style={s.commandWrap}>
          {cell && cell.redirect ? cell.warn && <div style={s.mtpWarn}>⚠️ {renderWarn(cell.warn)}</div> : <>
            <div style={s.commandHeader}>
              <div style={s.headerLeft}>
                <div style={s.badge(verifyStatus)}>
                  <span style={s.badgeDot(verifyStatus)} />
                  {VERIFY_LABEL[verifyStatus]}
                </div>
                <div style={s.runModeWrap} role="tablist" aria-label="Output format">
                  {runModes.map((mode, index) => <span key={mode} className="sg-command-visualizer-tab" style={{
    ...index === runModes.length - 1 ? s.runModeChipLast(activeRunMode === mode) : s.runModeChip(activeRunMode === mode),
    ...runModes.length === 1 ? {
      borderRadius: 7
    } : {}
  }} onClick={() => setRunMode(mode)} onKeyDown={e => {
    if (e.key !== "Enter" && e.key !== " ") return;
    e.preventDefault();
    setRunMode(mode);
  }} role="tab" tabIndex={0} aria-selected={activeRunMode === mode}>
                      {mode === "docker" ? "Docker" : "Python"}
                    </span>)}
                </div>
              </div>
              <div style={s.iconRow}>
                <button style={s.iconButton} onClick={handleCopy}>
                  {copied ? "✓ Copied" : "⧉ Copy"}
                </button>
                <button style={s.iconButton} onClick={() => setModal("curl")}>$ cURL</button>
                <button style={s.iconButton} onClick={() => setModal("env")}>⚙ Env</button>
              </div>
            </div>
            <pre style={s.commandPre}>{command}</pre>
            {cell && cell.warn && <div style={s.mtpWarn}>⚠️ {renderWarn(cell.warn)}</div>}
            {mtpHint && <div style={s.mtpWarn}>
                ⚠️ Speculative decoding ({specAlgoName}) is on — SGLang resets <code>--max-running-requests</code> to <strong>48</strong> when it isn't set. Add <code>--max-running-requests &lt;N&gt;</code> sized for your target concurrency.
              </div>}
            {specPinnedHint && <div style={s.mtpWarn}>
                ℹ️ Speculative decoding ({specAlgoName}) is on and this recipe pins <code>--max-running-requests</code> to <strong>{specMrrValue}</strong>. Adjust it to match your target concurrency — if you remove the flag, SGLang falls back to <strong>48</strong>.
              </div>}
          </>}
        </div>
      </div>

      {}
      {benchmarks && cell && renderBenchmarkCard(benchEntry)}

      {}
      {config.showPlaygroundLink !== false && <div style={{
    padding: "6px 12px",
    fontSize: "12px",
    color: isDark ? "#9ca3af" : "#6b7280",
    display: "flex",
    alignItems: "center",
    gap: "6px"
  }}>
          <span>Need to go beyond the verified matrix?</span>
          <button type="button" onClick={() => {
    const el = document.getElementById("playground");
    if (el) el.scrollIntoView({
      behavior: "smooth",
      block: "start"
    });
  }} style={{
    background: "transparent",
    border: "none",
    padding: 0,
    color: isDark ? "#FDBA74" : "#C2410C",
    cursor: "pointer",
    fontSize: "12px",
    fontWeight: 600,
    textDecoration: "underline",
    textUnderlineOffset: "2px"
  }}>
            Open the Playground →
          </button>
        </div>}

      {}
      {agenticLink && <div style={{
    padding: "0 12px 6px",
    fontSize: "12px",
    color: isDark ? "#9ca3af" : "#6b7280",
    display: "flex",
    flexWrap: "wrap",
    alignItems: "center",
    gap: "2px 6px"
  }}>
          <span>Need to serve Agentic Long-Context workloads?</span>
          <button type="button" onClick={() => {
    const el = document.getElementById(agenticLink);
    if (el) el.scrollIntoView({
      behavior: "smooth",
      block: "start"
    });
  }} style={{
    background: "transparent",
    border: "none",
    padding: 0,
    color: isDark ? "#FDBA74" : "#C2410C",
    cursor: "pointer",
    fontSize: "12px",
    fontWeight: 600,
    textDecoration: "underline",
    textUnderlineOffset: "2px",
    whiteSpace: "nowrap"
  }}>
            Refer to the Agentic Long-Context section →
          </button>
        </div>}

      {}
      {modal === "curl" && <div style={s.modalBackdrop} onClick={() => setModal(null)}>
          <div style={s.modalBox} onClick={e => e.stopPropagation()}>
            <div style={s.modalHeader}>
              <div style={s.modalTitle}>cURL example</div>
              <button style={s.modalCloseBtn} onClick={() => setModal(null)} aria-label="Close">×</button>
            </div>
            <div style={s.commandWrap}>
              <div style={s.commandHeader}>
                <div style={{
    fontSize: 11,
    opacity: 0.7
  }}>
                  Model: <code>{modelName || "(unresolved)"}</code>
                </div>
                <button style={s.iconButton} onClick={copyCurl}>
                  {curlCopied ? "✓ Copied" : "⧉ Copy"}
                </button>
              </div>
              <pre style={s.commandPre}>{curlText}</pre>
            </div>
            <p style={{
    fontSize: 11,
    opacity: 0.7,
    marginTop: 8
  }}>
              Edit <code>CURL_HOST</code> / <code>CURL_PORT</code> in the Env panel.
            </p>
          </div>
        </div>}

      {}
      {modal === "env" && <div style={s.modalBackdrop} onClick={() => setModal(null)}>
          <div style={s.modalBox} onClick={e => e.stopPropagation()}>
            <div style={s.modalHeader}>
              <div style={s.modalTitle}>Env / placeholder values</div>
              <button style={s.modalCloseBtn} onClick={() => setModal(null)} aria-label="Close">×</button>
            </div>
            {placeholderGroups.curl.length > 0 && <div>
                <div style={s.sectionHeading}>cURL placeholders</div>
                {placeholderGroups.curl.map(({key, label}) => <div key={key} style={s.formField}>
                    <label style={s.formLabel}>
                      {label} <code style={{
    opacity: 0.6
  }}>{`{{${key}}}`}</code>
                    </label>
                    <input style={s.formInput} value={envDraft[key] ?? ""} onChange={e => setEnvDraft({
    ...envDraft,
    [key]: e.target.value
  })} />
                  </div>)}
              </div>}
            {placeholderGroups.command.length > 0 && <div>
                <div style={s.sectionHeading}>Command placeholders</div>
                {placeholderGroups.command.map(({key, label}) => <div key={key} style={s.formField}>
                    <label style={s.formLabel}>
                      {label} <code style={{
    opacity: 0.6
  }}>{`{{${key}}}`}</code>
                    </label>
                    <input style={s.formInput} value={envDraft[key] ?? ""} onChange={e => setEnvDraft({
    ...envDraft,
    [key]: e.target.value
  })} />
                  </div>)}
              </div>}
            <div style={{
    display: "flex",
    justifyContent: "flex-end",
    gap: 8,
    marginTop: 16
  }}>
              <button style={{
    ...s.iconButton,
    padding: "6px 14px"
  }} onClick={() => setModal(null)}>Cancel</button>
              <button style={s.primaryBtn} onClick={() => {
    saveEnv(envDraft);
    setModal(null);
  }}>Save</button>
            </div>
            <p style={{
    fontSize: 11,
    opacity: 0.7,
    marginTop: 10
  }}>
              Values persist in localStorage and are reused the next time you visit any cookbook.
            </p>
          </div>
        </div>}

      {}
      {modal === "bench" && benchEntry && (() => {
    const bc = buildBenchCommands(benchEntry, sel);
    if (!bc) return null;
    const selSummary = [sel.hw && sel.hw.toUpperCase(), sel.variant, sel.quant && sel.quant.toUpperCase(), sel.strategy, sel.kvDsaPair, sel.nodes].filter(part => part !== undefined && part !== null && part !== "").join(" · ");
    let selConc = null;
    let speedCmd = null;
    if (bc.speed) {
      selConc = bc.speed.concurrencies.includes(benchConc) ? benchConc : bc.speed.concurrencies[0];
      const w = bc.speed.workload;
      speedCmd = interpolate(bc.speed.template, {
        ...env,
        DATASET: w.dataset,
        ISL: w.isl,
        OSL: w.osl,
        MAX_CONCURRENCY: selConc,
        NUM_PROMPTS: bc.speed.numPromptsOf(selConc)
      }, modelName);
    }
    let selAcc = null;
    let accCmd = null;
    if (bc.accuracy.length > 0) {
      selAcc = bc.accuracy.find(a => a.key === benchAcc) || bc.accuracy[0];
      accCmd = interpolate(selAcc.template, env, modelName);
    }
    return <div style={s.modalBackdrop} onClick={() => setModal(null)}>
            <div style={s.modalBox} onClick={e => e.stopPropagation()}>
              <div style={s.modalHeader}>
                <div style={s.modalTitle}>Benchmark commands</div>
                <button style={s.modalCloseBtn} onClick={() => setModal(null)} aria-label="Close">×</button>
              </div>
              <p style={{
      fontSize: 11,
      opacity: 0.7,
      margin: "0 0 12px"
    }}>
                For <code>{selSummary}</code>. Start the server with the Deploy command above, then run these against it.
              </p>

              {selAcc && <div>
                  <div style={s.sectionHeading}>Accuracy</div>
                  {bc.accuracy.length > 1 && <div style={s.benchChipRow}>
                      <span style={{
      fontSize: 11,
      opacity: 0.7
    }}>benchmark:</span>
                      {bc.accuracy.map(a => <button key={a.key} style={{
      ...s.benchChip,
      ...a.key === selAcc.key ? s.benchChipActive : {}
    }} onClick={() => setBenchAcc(a.key)}>
                          {a.label}
                        </button>)}
                    </div>}
                  <div style={{
      ...s.commandWrap,
      marginBottom: 6
    }}>
                    <div style={s.commandHeader}>
                      <div style={{
      fontSize: 11,
      opacity: 0.7
    }}>{selAcc.label}</div>
                      <button style={s.iconButton} onClick={() => copyBench("acc", accCmd)}>
                        {benchCopied === "acc" ? "✓ Copied" : "⧉ Copy"}
                      </button>
                    </div>
                    <pre style={s.commandPre}>{accCmd}</pre>
                  </div>
                  {bc.accuracy.length > 1 && <p style={{
      fontSize: 11,
      opacity: 0.7,
      margin: "0 0 4px"
    }}>
                      Switch the benchmark chip to see each eval's command.
                    </p>}
                </div>}

              {bc.speed && <div>
                  <div style={s.sectionHeading}>Speed</div>
                  {bc.speed.concurrencies.length > 1 && <div style={s.benchChipRow}>
                      <span style={{
      fontSize: 11,
      opacity: 0.7
    }}>max-concurrency:</span>
                      {bc.speed.concurrencies.map(c => <button key={c} style={{
      ...s.benchChip,
      ...c === selConc ? s.benchChipActive : {}
    }} onClick={() => setBenchConc(c)}>
                          {c}
                        </button>)}
                    </div>}
                  <div style={{
      ...s.commandWrap,
      marginBottom: 6
    }}>
                    <div style={s.commandHeader}>
                      <div style={{
      fontSize: 11,
      opacity: 0.7
    }}>max-concurrency = {selConc}</div>
                      <button style={s.iconButton} onClick={() => copyBench("speed", speedCmd)}>
                        {benchCopied === "speed" ? "✓ Copied" : "⧉ Copy"}
                      </button>
                    </div>
                    <pre style={s.commandPre}>{speedCmd}</pre>
                  </div>
                  <p style={{
      fontSize: 11,
      opacity: 0.7,
      margin: "0 0 4px"
    }}>
                    One command — switch the concurrency chip (or edit <code>--max-concurrency</code>) to reproduce each Speed column.
                  </p>
                </div>}

              <p style={{
      fontSize: 11,
      opacity: 0.7,
      marginTop: 12
    }}>
                Edit <code>CURL_HOST</code> / <code>CURL_PORT</code> in the Env panel.
              </p>
            </div>
          </div>;
  })()}
    </div>;
};

export const DiffusionModelTags = ({tags = []}) => {
  const normalizedTags = Array.isArray(tags) ? tags : [tags];
  return <div className="not-prose sgd-model-tags">
      {normalizedTags.map(tag => <span key={tag} className="sgd-chip">
          {tag}
        </span>)}
    </div>;
};

<DiffusionModelTags tags={["image", "5.6B DiT", "text-to-image / image editing", "up to 10 references", "Base / step-distilled"]} />

## 1. Quick start

Use a [SGLang Diffusion Docker environment](/docs/sglang-diffusion/installation).
Until a released image contains this integration, install SGLang from `main`
inside it:

```bash theme={null}
pip install 'sglang[diffusion] @ git+https://github.com/sgl-project/sglang.git#subdirectory=python'
```

<Deployment config={config} />

<Note>
  The picker selects `black-forest-labs/flux-3-image-klein-base` or
  `black-forest-labs/flux-3-image-klein`, each a self-contained repository. Access
  to the selected checkpoint is required. Keep `--model-path` at its repository
  root; `--model-variant` selects only the quantized DiT. Both release BF16
  checkpoints have single-GPU generation checks; see the validation boundaries
  below. Unverified hardware or resource shapes remain selectable but are not
  measured recommendations.
</Note>

<Warning>
  FLUX.3 Image Klein is released under the
  [FLUX Kommunity License v1.0](https://huggingface.co/black-forest-labs/flux-3-image-klein/blob/main/LICENSE.md):
  non-commercial use, plus commercial output generation for Qualifying Users with
  less than US\$5M in gross annualized revenue, subject to its terms. The
  Qwen3-VL-4B-Instruct text encoder is Apache-2.0. Review the license before
  production or commercial use.
</Warning>

For platform-specific installation, see the
[SGLang Diffusion installation guide](/docs/sglang-diffusion/installation).

## 2. Model capabilities

[FLUX.3 Image Klein](https://huggingface.co/collections/black-forest-labs/flux-3-image-klein)
is Black Forest Labs' 5.6B open-weights model for text-to-image generation and
image editing. It takes a prompt and up to 10 reference images and returns one
image; text-to-image, single-reference edits and multi-reference compositions
run through the same DiT, with Qwen3-VL-4B-Instruct as the text encoder. The
5.6B count covers the image transformer only.

Prompts can place elements with bounding boxes on a 0 to 1000 grid, then
recolor, move, replace or remove them; boxes guide placement and scale rather
than masking pixels. The model also renders text inside images. One SGLang
server serves text-to-image and editing, chosen per request. This image
pipeline does not serve the separate FLUX.3 Action robot policy.

| Checkpoint | Training | Steps | Guidance | Built for |
| - | - | - | - | - |
| [Klein](https://huggingface.co/black-forest-labs/flux-3-image-klein) | step-distilled flow map | 16 | none | generation and editing, self-hosting; the checkpoint behind the BFL API |
| [Klein Base](https://huggingface.co/black-forest-labs/flux-3-image-klein-base) | undistilled | 50 | 3.5 | fine-tuning, LoRA training, research |

Each repository ships its BF16 DiT with FP8 (`fp8r`) and NVFP4 variants,
together with the text encoder and image autoencoder. Quantization and caching
are separate fidelity/latency tradeoffs, not lossless substitutes for the
selected checkpoint.

| Task | Endpoint | Conditioning |
| - | - | - |
| Text to image | `POST /v1/images/generations` | Text prompt |
| Image to image | `POST /v1/images/edits` | Text prompt and 1 to 10 `image` uploads |

Start the server:

```bash theme={null}
sglang serve \
  --model-path black-forest-labs/flux-3-image-klein-base \
  --host 0.0.0.0 \
  --port 30010
```

Sampling is set per request (`num_inference_steps`, `guidance_scale`, `size`,
`seed`, `n`); unset fields take the checkpoint's defaults from its
`config.json`. SGLang expands `n` into independently seeded requests and can
pack compatible requests into one DiT forward.

References are prepared as in the
[BFL reference pipeline](https://github.com/black-forest-labs/flux-3-image-klein).
A single reference is
fitted under 4 MP, reflect-padded to the 16-pixel grid and, when you set no
output size, sets the output size; the padding is cropped from the result.
With several references each is fitted under 1 MP and centre-cropped, and the
output takes the first one's size.

### Prompting

The caption controls composition; reference images anchor content but do not
lock structure.

* Write full scene captions covering framing, subject, background and lighting.
  A short prompt gives generic output, and a one-line edit instruction ("make it
  blue") reframes the shot. The [prompt upsampler](#7-prompt-upsampler) expands
  a short request into a full caption.
* For edits, describe the target image as a complete caption of the reference
  with the edit folded in.
* For layout, append a JSON list of elements to the caption. Each box is
  `[top, left, bottom, right]` on a 0 to 1000 grid, and the caption tags each
  element as `<id>`. To edit by box, refer to the n-th reference as
  `<ref_image_n>` and give each element `from`, `src_bbox` and `tgt_bbox`; a
  `null` target removes it. See BFL's
  [bounding box guide](https://docs.bfl.ai/flux_3/flux3_image_bounding_boxes)
  for the full format.

## 3. Checkpoints and precision

| Repository | `--model-variant` | Sampling |
| - | - | - |
| `black-forest-labs/flux-3-image-klein-base` | Omit / `fp8r` / `nvfp4` | Base CFG; defaults from the selected configuration |
| `black-forest-labs/flux-3-image-klein` | Omit / `fp8r` / `nvfp4` | Step-distilled flow map; no CFG |

Both repositories use `flux-3-image-klein` in configuration and safetensors
metadata. This shared identifier does not determine the sampling mode. The
release repositories do not need the pre-release `sd-*` variant names.

The distilled model is a step-distilled flow-map DiT: each step jumps straight
to the next time of the schedule, so it samples without CFG. SGLang tells a
flow map from its weights. It rejects `--enable-cfg-parallel`, a request
`guidance_scale` other than 1, and a non-empty `negative_prompt`. Tensor
parallelism, Ulysses SP and breakable CUDA graphs work as for the base model.

The Base model defaults to CFG 3.5 against an empty negative prompt. Both
variants reuse the package's text encoder and VAE. Keep the checkpoint revision,
precision, attention backend, guidance and sampling parameters fixed when
comparing outputs.
Explicit `guidance_scale=1` uses scale 1, not the package default;
`true_cfg_scale`, when provided, takes precedence over `guidance_scale`.

### Quantized checkpoints

Each repo ships quantized DiTs under `variants/`: select one with
`--model-variant fp8r` or `--model-variant nvfp4` and keep `--model-path`
pointing at the repo root. Text encoder and VAE precision follow their own
package settings; quantizing the DiT does not quantize them. The quantization
comes from the variant's `hf_quant_config.json`, so do not also pass
`--quantization`.

```bash theme={null}
sglang serve \
  --model-path black-forest-labs/flux-3-image-klein-base \
  --model-variant fp8r \
  --host 0.0.0.0 \
  --port 30010
```

**FP8R** stores rowwise-FP8 weights. On Blackwell (SM10x) the FP8 projections
run FlashInfer PrimsTS GEMMs with fused QK-norm/RoPE and SwiGLU epilogues
(FlashInfer >= 0.7.1); set `SGLANG_ENABLE_FLUX3_PRIMS_TS_AUTOTUNE=1` to
autotune them during warmup. Other GPUs use the generic rowwise-FP8 GEMM.

**NVFP4** stores FP4 (E2M1) weights with FP8 block scales and needs a Blackwell
GPU and a compatible GEMM implementation. SM10x and consumer SM120 use
different kernel paths; a B200 recipe does not establish RTX 5090 performance.
Both quantization modes can change output quality and need workload-specific
comparison against BF16.

These flags remain separately configurable; see the validation boundaries below
before combining quantization with other optimizations.

### LoRA adapters

Use the standard LoRA API with native DiT keys, optionally prefixed by `dit.` or
`transformer.`. BF16 dynamic and merged adapters have a synthetic rank-4 generation
check, including repeatability and exact restoration after unloading; this does
not validate every community adapter. For quantized deployments requiring LoRA,
pass `--lora-path` at startup to select the generic quantized layout. Attaching
LoRA after PrimsTS weight preparation is rejected before replacing any layers.
Quantized LoRA combinations still need separate end-to-end validation.

## 4. Multi-GPU and memory

FLUX.3 shares its DiT with FLUX.3 Action, so the image pipeline supports
tensor parallelism, Ulysses sequence parallelism, CFG parallelism, layerwise
offload and breakable CUDA graphs. The picker covers RTX 5090, RTX PRO 6000,
H100/H200, and B200/B300/GB200/GB300 with one to eight GPUs on one node.
TP times Ulysses degree must equal the GPU count and evenly partition the
24 attention heads. Ring is not admitted by this image recipe.

For example, two-GPU TP uses `--num-gpus 2 --tp-size 2`; two-GPU Ulysses
uses `--num-gpus 2 --tp-size 1 --ulysses-degree 2`. Base also permits CFG
parallelism; distilled checkpoints have no CFG branch to parallelize.
More GPUs do not guarantee lower latency, particularly over PCIe.

<Note>
  Under sequence parallelism every rank holds the full DiT, so combining it with
  layerwise offload streams the whole model to each GPU every step. TP also
  partitions weights, so it is the lower-memory starting point when offloading
  on several GPUs. Preserve headroom for the longest prompt, references and output
  size you intend to serve; a successful small request is not a capacity guarantee.
</Note>

For FP32 VAE attention above 1 MP, `quality="lossless"` can use dense-layout,
full-context memory-efficient SDPA; `quality="exact"` retains the original path.
It does not prune attention or reduce precision, but reduction order can change
pixels. In a Base BF16 test with a 2048x2048 reference and 1024x1024 output,
GB300 peak allocated memory fell from 54.3 to 29.5 GiB; latency was effectively
unchanged. GB300/H200 image SSIM was 0.9951-0.9992 against the exact path across
four samples. This is allocated memory, not total device usage: a 32 GB card
still needs offload or quantization headroom for that reference size.

## 5. Cache-DiT

[Cache-DiT](/docs/sglang-diffusion/cache_dit) skips the 28 single-stream blocks
on steps where their input barely changes and reuses the cached residual. Turn
it on for every request with `SGLANG_CACHE_DIT_ENABLED=true` on `sglang serve`,
or per request with `"enable_cache_dit": true`. A request can also tune it, for
example `"cache_dit_params": {"residual_diff_threshold": 0.12, "enable_taylorseer": true}`.

For image editing, send `-F "enable_cache_dit=true"` and a JSON-encoded
`cache_dit_params` form field; generation uses JSON request fields.

Cache-DiT is approximate and may change composition; measure quality and latency
on representative prompts rather than treating its threshold as a fidelity guarantee.
It combines with FP8R and NVFP4, tensor parallelism, CFG parallelism and
layerwise offload. It is skipped, with a warning, under Ulysses sequence
parallelism and breakable CUDA graphs, and for a request whose CFG pair has to
run as two forwards to fit in device memory.

## 6. Request examples

<Tabs>
  <Tab title="Text to image">
    ```bash theme={null}
    curl -sS -X POST http://localhost:30010/v1/images/generations \
      -H 'Content-Type: application/json' \
      -d '{"prompt": "A red fox standing in fresh snow", "size": "1024x1024", "seed": 0, "response_format": "b64_json"}' \
      -o flux3_t2i.json
    ```
  </Tab>

  <Tab title="Image to image">
    ```bash theme={null}
    curl -sS -X POST http://localhost:30010/v1/images/edits \
      -F "image=@/data/flux3/reference.png" \
      -F "prompt=Render the reference as a winter wildlife photograph" \
      -F "seed=0" \
      -F "response_format=b64_json" \
      -o flux3_i2i.json
    ```
  </Tab>

  <Tab title="Offline generation">
    ```bash theme={null}
    sglang generate \
      --model-path black-forest-labs/flux-3-image-klein-base \
      --height 1024 --width 1024 \
      --num-inference-steps 50 \
      --guidance-scale 3.5 \
      --prompt "A red fox standing in fresh snow"
    ```

    Pass `--image-path` (one or more images) to edit references instead.
  </Tab>
</Tabs>

## 7. Prompt upsampler

[black-forest-labs/flux-3-image-klein-pup](https://huggingface.co/black-forest-labs/flux-3-image-klein-pup)
is a Qwen3.5-9B vision-language fine-tune that expands a short prompt into the detailed
caption FLUX.3 works best with. The BFL reference code runs it in front of the image model
by default. It is a standard `Qwen3_5ForConditionalGeneration` checkpoint, so it is served
as a regular LLM, separately from the image pipeline. The system prompt (`system_prompts.json`
in the repository) selects the mode; `t2i` is the text-to-image upsampler.

Download the package and start the upsampler on its own port:

```bash theme={null}
PUP_PATH="<local-path>"
hf download black-forest-labs/flux-3-image-klein-pup --local-dir ${PUP_PATH}

CUDA_VISIBLE_DEVICES=1 sglang serve ${PUP_PATH} \
      --model-type llm \
      --served-model-name flux-3-image-klein-pup \
      --host 0.0.0.0 --port 8001 \
      --context-length 16384 \
      --mem-fraction-static 0.90 \
      --reasoning-parser qwen3
```

Upsample a text prompt through the OpenAI-compatible chat endpoint. The `t2i` system
prompt is read from the downloaded package; thinking is disabled and decoding follows the
model card (greedy, presence penalty 1.5):

```bash theme={null}
jq -n --slurpfile p ${PUP_PATH}/system_prompts.json '{
    model: "flux-3-image-klein-pup",
    messages: [
      {role: "system", content: $p[0].t2i},
      {role: "user",   content: "A man walking with his dog, afternoon sun"}
    ],
    max_tokens: 3584,
    temperature: 0,
    presence_penalty: 1.5,
    chat_template_kwargs: {enable_thinking: false}
  }' | curl -s http://0.0.0.0:8001/v1/chat/completions \
         -H 'Content-Type: application/json' -d @- \
     | jq -r '.choices[0].message.content'
```

You can then pass the returned caption as the `--prompt` of a `t2i` request to the Flux3 pipeline.

## 8. Dynamic batching

Enable a small batching window to collect concurrent requests:

```bash Serve concurrent requests theme={null}
sglang serve --model-path black-forest-labs/flux-3-image-klein-base \
  --batching-max-size 2 --batching-delay-ms 5
```

The existing scheduler groups requests with matching sampling/runtime settings.
Each keeps its own prompt, seed and reference images. Text encoding groups unique
prompts by token-length bucket; DiT attention remains isolated per packed sample,
including each CFG branch. VAE decoding groups outputs by canvas size before
restoring request order and each reference crop.

Larger batches need more activation memory and may increase individual request
latency. Start with batch 2, compare throughput and tail latency under your actual
QPS, and keep batch 1 for low-latency or low-VRAM workloads. Batching does not imply
bitwise equality with separate forwards: GEMM and attention reduction choices can
change with shape. Check output fidelity with fixed prompts and seeds.

### Pre-release batching measurements

These measurements used pre-release weights, not the release repositories
above. They do not establish release-checkpoint performance.

The following are warmed HTTP measurements on one GB300 (about 277 GiB device
memory), Base BF16, Torch SDPA, eager execution and all components resident.
Each row compares two different prompt/seed requests served serially with the
same two requests served together. Times include local HTTP transfer and JPEG
output; medians cover three rounds after warming both shapes and reference
encoding. Software: PyTorch 2.14.1+cu130, Transformers 5.19.0. Checkpoint revision:
`5de4fe32f17aee3dbc34375a94935f09206dba2c`.

| Workload | Serial pair | Batch-2 pair | Throughput ratio |
| - | - | - | - |
| T2I, 512x512, 8 steps | 0.649 s | 0.324 s | 2.00x |
| I2I, 512x512, 8 steps | 0.737 s | 0.546 s | 1.35x |
| T2I, 1024x1024, 50 steps | 6.248 s | 6.050 s | 1.03x |
| I2I, 1024x1024, 50 steps | 13.171 s | 12.996 s | 1.01x |

Eight steps exercise batching, not the recommended Base image-quality setting.
The standard 50-step workload shows little batching benefit;
FlashAttention gives a similarly small gain in this
setup. Batch 1 remains the default. Do not extrapolate the small-request speedup
to full-resolution generation or other GPUs.

For these 50-step requests, batch-1 versus batch-2 JPEG outputs had SSIM
0.9920-0.9977. A separate four-image PNG comparison at 512x512/8 steps had SSIM
0.9885-0.9955; JPEG can amplify small rounding differences. These are observed
samples, not a universal quality guarantee. Identical single requests before
and after batching matched exactly. Preserve additional memory headroom for
batching rather than assuming a batch-1 recipe fits on a 32 GB card at batch 2.

## 9. Validation boundaries

The release BF16 and FP8R checkpoints have single-GB300/H200 generation checks;
NVFP4 has GB300 checks. Base BF16 also has an RTX 5090 check. Each uses eager
execution, all components resident, batch 1, 1024x1024 T2I and I2I, two
prompts/seeds and repeated requests. Base uses 50 steps and distilled uses 16.
Repeated requests matched pixel-for-pixel within each tested configuration.
This does not establish official-reference parity or validate every combination
of hardware, parallelism, batching and optional features in the picker.

### Single-GPU measurements

Warmed local HTTP medians, including PNG encoding and response transfer, from
two rounds per prompt. PyTorch 2.14.1+cu130, Transformers 5.19.0, FP32 VAE,
`quality="exact"`; FlashAttention on GB300/H200 and Torch SDPA on RTX 5090.
The Base checkpoint revision is `d8acde427a698bdb98b5c1c941c60fa4c97e9f28`.
SSIM compares each quantized result with BF16 on the same GPU, prompt, seed and
reference, and reports the lowest value across two samples, not a quality bound.

| GPU | Base DiT | T2I | I2I | Minimum SSIM, T2I / I2I |
| - | - | - | - | - |
| GB300, 277 GiB | BF16 | 3.21 s | 6.31 s | Reference |
| GB300, 277 GiB | FP8R | 2.18 s | 4.49 s | 0.958 / 0.981 |
| GB300, 277 GiB | NVFP4 | 2.14 s | 4.31 s | 0.919 / 0.958 |
| H200, 140 GiB | BF16 | 7.09 s | 14.52 s | Reference |
| H200, 140 GiB | FP8R | 5.15 s | 11.24 s | 0.955 / 0.984 |
| RTX 5090, 32 GB | BF16 | 20.39 s | 43.4 s | Reference |

For the distilled checkpoint, quantization's T2I benefit was small on GB300;
do not assume Base's speedup transfers to a 16-step workload. Cache-DiT at
threshold 0.12 reduced Base I2I from 6.31 to 3.08 s on GB300, with sample SSIM
0.9786-0.9975. It remains opt-in and approximate. Breakable CUDA graphs did not
provide a clear latency win in the tested GB300 workload; eager stays recommended.

The native DiT's packed CFG forward has focused comparison tests against the
shared FLUX 3 transformer. Such component tests do not replace full-checkpoint
E2E or establish parity with every upstream release. Keep unverified hardware,
topologies and optional optimizations separate from measured deployment recipes.

The opt-in full-checkpoint HTTP regression covers concurrent prompts, image
editing, multiple outputs and a repeated single request:

```bash theme={null}
SGLANG_TEST_FLUX3_IMAGE=1 pytest -q \
  python/sglang/multimodal_gen/test/server/test_server_flux3_image.py
```

Set `SGLANG_TEST_FLUX3_IMAGE_MODEL` to a local package path when using an
offline checkpoint. This test needs checkpoint access; it does not substitute
for an official-reference golden-image comparison.

## 10. ComfyUI

<ComfyUISupport model="image" note="FLUX.3 has no integrated KSampler executor. Use server mode; the plugin-specific FLUX.3 workflow has not been validated." />


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.