Qwen3.8-27B

Qwen3.8-27B

Qwen3.8-27B는 밀집 하이브리드 Gated Delta Networks (GDN) 비전-언어 모델이에요: 비전 인코더와 짝을 이루는 27B 인과 언어 모델로, 텍스트와 함께 네이티브 이미지·비디오 이해를 제공해요. SGLang은 이를 Qwen3-VL 경로로 서빙하므로 아래 레시피들에서는 비전 타워가 활성화돼 있어요.

출처: 문서

본문

1. 모델 소개

언어 모델은 64개 레이어로, 3 × (Gated DeltaNet → FFN)1 × (Gated Attention → FFN) 의 16회 반복으로 배치돼요 — 48개 선형-어텐션 레이어 대 16개 전체-어텐션 레이어. Gated DeltaNet은 head_dim 128에서 48개의 value 헤드와 16개의 QK 헤드를 실행하고, Gated Attention은 head_dim 256에서 64차원 rotary 슬라이스를 가진 GQA 24/4예요. 히든 크기는 17,408-차원 FFN 위에 5120이며, 체크포인트는 여러 단계로 학습된 MTP 헤드를 갖고 있어요. 컨텍스트는 네이티브 262,144 토큰, 1,000,000까지 확장 가능해요. 서빙 관련 아키텍처는 Qwen3.6-27B와 동일해요.

Thinking 모드는 기본적으로 켜져 있고 요청별로 비활성화할 수 있어요. 추론 깊이는 reasoning_effort로 조절 가능하며, preserve_thinking은 이전 메시지의 추론 컨텍스트를 유지해요.

Model Quantization Weights
Qwen3.8-27B BF16 Qwen/Qwen3.8-27B
Qwen3.8-27B-FP8 FP8 (blockwise) Qwen/Qwen3.8-27B-FP8
Qwen3.8-27B-NVFP4 (FP4 head) NVFP4 W4A4 + FP8 projections, lm_head packed to FP4 RadixArk/Qwen3.8-27B-NVFP4
Qwen3.8-27B-NVFP4 (BF16 head) Same body, lm_head left dense in BF16 RadixArk/Qwen3.8-27B-NVFP4-BF16-LMHead
Qwen3.8-27B-NVFP4 (NVIDIA) NVIDIA's ModelOpt export of the same W4A4 body, lm_head packed to FP4 nvidia/Qwen3.8-27B-NVFP4

두 RadixArk NVFP4 내보내기는 lm_head에서만 달라요: 하나는 FP4로 패킹하고, 다른 하나는 BF16에서 밀집으로 남겨요. 밀집 헤드는 디스크에서 ~1.7 GB, 런타임에서 ~3.2 GB 더 커서, 맞추기 더 어려운 쪽이에요 — 이 페이지의 모든 레시피가 그것에 맞춰 측정됐고, FP4-헤드 셀들은 그 핀을 그대로 재사용해요.

NVIDIA 자체 내보내기는 같은 W4A4 본체에 같은 FP4 헤드가 붙은 것: 동일한 양자화 레이어 맵(FP8 어텐션·GDN 프로젝션, NVFP4 MLP), 동일한 텐서 집합, 디스크에서 동일한 21.9 GB. GB300, RTX PRO 6000, DGX Spark에서 해당 셀은 FP4-헤드 핀을 그대로 재사용하며, 두 SM12x 그리드가 v0.5.19에서 이 내보내기로 다시 측정됐어요: 카드당 16개 오버레이 조합 모두가 전체 1319-문항 GSM8K에서 94.01-95.00%(RTX PRO 6000), 94.16-95.07%(DGX Spark)를 서빙·득점해요.

RTX 5090도 측정됐어요 — 제공하는 15개 오버레이 조합 모두가 93.93-94.92%를 서빙·득점 — 그리고 그곳의 모든 우승 실행 명령은 FP4-헤드 내보내기의 것과 동일한데, 이는 위 주장의 가장 강한 형태예요. 32GB 카드가 필요로 하는 것은 드래프트 모델 행이 자신의 풀을 핀으로 고정하는 일이에요: 그 레시피는 --max-running-requests 1을 핀으로 고정하지만, 풀을 그에 맞춰 제한하지는 않아서 KV 풀이 8192-in/1024-out 요청 하나가 필요로 하는 9,216에 맞게 자기 크기를 127,332 토큰으로 정하고, 드래프트 모델 가중치가 --mem-fraction-static에 계산되면 엔진 기본 분할은 GDN 상태 풀을 필요한 슬롯 수에 크게 못 미치게 남겨요. 그래서 DSPARK 행은 float32 상태의 밀집-lm_head 내보내기에서 DFLASH2와 MTP처럼 --max-total-tokens와 측정된 --mamba-full-memory-ratio를 핀으로 고정해요. 이러한 핀은 그 핀을 지니는 선택에 대해 계산기의 실시간 값을 대체해요. 추측 없음 행은 어떤 것도 필요로 하지 않고 표시된 핀에서 실행돼요.

두 RadixArk 체크포인트는 kv_cache_quant_algo: FP8을 선언하므로, SGLang 기본 --kv-cache-dtype auto는 그들의 KV 풀을 이미 fp8_e4m3에 둬요. NVIDIA 내보내기는 kv_cache_scheme을 제공하지 않아 auto는 그 풀을 대신 BF16에 남길 거예요. 이 페이지의 모든 레시피는 --kv-cache-dtype fp8_e4m3을 명시적으로 핀 고정해, 세 개 모두 속에 관계없이 같은 fp8_e4m3 풀을 실행해요. 차이는 Playground의 KV Cache Precision 행을 Auto로 되돌릴 때만 나타나요.

2. 구성 팁

  • SM120/SM121 (RTX PRO 6000 Blackwell, RTX 5090, DGX Spark): --attention-backend flashinfer를 사용하세요. trtllm_mha는 SM100 전용이에요. FlashInfer 백엔드의 MTP는 prefill planuniform_q_len(0.6.15.post1보다 최신)을 받아들이는 FlashInfer 빌드가 필요해요. 그렇지 않으면 --attention-backend triton으로 spec을 실행하세요. DGX Spark에서 128GB는 호스트 CPU와 공유되는 통합 메모리라 세 체크포인트 모두 맞고, 그 셀들은 별도 operating point가 아니라 --mem-fraction-static 0.80에서 RTX PRO 6000 레시피를 재사용해요. 유일하게 낮은 핀은 통합 풀이 호스트 메모리까지 계산하는 점이에요: 128GB의 0.85는 OS에 ~8GB를 남기는데 — 정확히 DGX OS earlyoom의 SIGTERM 임계값 — 최초 장문 prefill이나 부팅 시 그래프 캡처가 그 아래로 내려가 트레이스백 없이 exit code -15로 스케줄러가 죽어요(journalctl -u earlyoom이 kill을 보여줘요). 0.85에서 48개 셀 중 15개가 그렇게 죽었고, 어느 셀인지는 여백 노이즈예요. 0.80에서는 모든 시도에서 모든 셀이 서빙됐어요. SM121 / aarch64에서 검증됨: 80개 구성(5개 체크포인트 x 추측 디코딩 x 서빙 전략 x Mamba SSM Dtype, DFLASH2 포함) 모두가 v0.5.19의 GB10에서 ISL 8192 / OSL 1024, 동시성 1로 서빙하고, 각각 전체 1319-문항 GSM8K를 득점했어요(93.18-95.15%). float32와 bfloat16 절반은 두 개의 별도 GB10 박스에서 돌았어요. 처리량이나 수용-길이 수치는 다시 측정되지 않았어요. 이 스윕은 위의 FlashInfer plan / uniform_q_len 경로를 실행했는데, 그 빌드에서 arity 오류를 일으키지 않았어요. GB10에서 재현할 때의 세 가지 호스트 특이점: docker GPU 접근은 CDI 전용이에요(--device nvidia.com/gpu=all, 등록된 nvidia 런타임이 없으므로). nvidia-smi는 CPU와 통합돼 메모리에 대해 Not Supported를 보고하므로, 대신 /proc/meminfoMemAvailable로 재시작을 게이트하세요. 그리고 BF16 체크포인트는 NVMe에서 18개 샤드를 로드하는 데만 ~6.5분 걸리므로, 부팅이 멈췄다고 부르기 전에 READY까지 ~10분을 예산 잡으세요.
  • H200 (SM90): BF16과 FP8만 — 카드에는 FP4 텐서 코어가 없어서 NVFP4 체크포인트의 MLP가 Marlin W4A16 weight-only 경로로 폴백하고, 세 NVFP4 셀이 모두 회색 처리돼요. H200 레시피는 32768-토큰 prefill 청크를 사용해요(SM90 prefill은 커서 큰 청크가 decode를 간신히 지연시키는데, 아래 SM120 안내와 다름). FlashInfer GDN prefill 백엔드가 그 아래에서 기본적으로 개입해요. --attention-backend fa3도 유효한 대안이며 bs=1에서 약간 더 빠르게 측정됐어요.
  • MTP: --speculative-algorithm EAGLE --speculative-num-steps 3 --speculative-eagle-topk 1 --speculative-num-draft-tokens 4가 체크포인트 내 MTP 헤드를 사용해요. (이 레시피는 원래 NEXTN으로 문서화됐는데, EAGLE의 별칭 — 같은 알고리즘.)
  • DSpark: 학습된 드래프트 모델은 별도 체크포인트예요 — --speculative-algorithm DSPARK --speculative-draft-model-path RadixArk/Qwen3.8-27B-DSpark를 추가하세요(Playground의 Speculative Decoding 카드가 이 쌍을 방출해요). DSpark는 --speculative-num-draft-tokens받지 않아요: 검증 윈도우는 --speculative-dspark-block-size(gamma) + 1이고, 플래그를 생략하면 gamma가 드래프트 체크포인트에서 자동 추론돼요(이 체크포인트는 7, 그래서 D = 8). 그 D는 균형 비율의 항이에요 — r = (S + D) x token_equiv / L, 여기서 token_equiv는 KV 토큰으로 표현된 상태 슬롯, state_bytes / kv_bytes_per_token(fp8 KV 위 fp32 상태 4698 / bf16 2394) — 이므로 DSpark는 같은 S에서 추측 없음보다 실질적으로 더 높은 --mamba-full-memory-ratio가 필요하고, 다른 gamma를 핀 고정하면 비율도 따라 바뀌어요. MTP는 반대 경우예요: --enable-linear-replayssm-spec로 드래프트 중간물이 고정 링 위로 이동해 D = 0이 되고 빛을 추측 없음 값으로 돌아가요. 계산기가 두 규칙을 적용해요.
  • DFlash2: 별도 체크포인트의 학습된 블록-디퓨전 드래프트 — --speculative-algorithm DFLASH --speculative-draft-model-path incoai/Qwen3.8-27B-DFlash2 --speculative-num-draft-tokens 8을 추가하세요(8은 드래프트의 블록 크기이며, 비율의 D 항이고 DSpark의 것과 같은 값). Ascend NPU에서도 실행돼요(#35629): 셀렉터 검증이 그곳에서 argmax로 폴백하는데, EAGLE와 1세대 DFlash 드래프트(예: z-lab/Qwen3-8B-DFlash-b16)가 NPU에서 이미 하는 것과 일치해요. 따라서 NPU는 현재 greedy 요청에 대해서만 무손실 검증을 보장해요. temperature=0top_k=1을 사용하세요. 비-greedy 요청은 경고를 로그하고, 드래프트 제안과 타겟 검증 모두 greedy로 폴백하므로 요청된 샘플링 분포가 보존되지 않아요. 셀렉터는 양자화된 헤드를 포함해 타겟 lm_head를 통해 후보를 투영하므로 NVFP4 체크포인트(헤드가 NVFP4-패킹됨; BF16·FP8 체크포인트는 밀집 헤드를 유지)에서도 실행돼요. #35629의 Ascend 비교는 BF16 타겟 가중치, --tp-size 2 --attention-backend ascend --mamba-ssm-dtype bfloat16 --mamba-radix-cache-strategy extra_buffer를 가진 A3 Series 장치를 사용했고, 캐시 워밍업과 prefix 재사용을 배제하려고 베이스라인과 DFlash2 모두에서 RadixCache를 비활성화했어요. DFlash2 실행은 위에 표시된 세 플래그를 추가했어요. 그 비교의 정확도는 greedy 샘플링, max_new_tokens=2048, 128개 예제, 그리고 동시성 수준 1, 2, 4, 8, 16의 zero-shot GSM8K를 사용했어요 — 이 페이지 자체 스윕과는 다른 프로토콜. 검증: 이 페이지의 모든 SM12x 셀이 v0.5.19에서 end-to-end로 측정됐어요 — 다섯 체크포인트, 네 추측 옵션, 두 서빙 계층, 두 GDN 상태 dtype에 걸쳐 202개 셀, 각각 전체 1319-문항 GSM8K, 93.18-95.15%. RTX PRO 6000과 DGX Spark 레시피는 변경이 필요 없어요. 32GB RTX 5090에서 패널은 측정된 핀을 자동 적용해요: DFlash2는 --mem-fraction-static 0.91 + --chunked-prefill-size 1024(0.91에서 풀은 들어맞지만 2048-토큰 청크의 활성화는 안 들어감), DSpark는 0.88(bfloat16), 0.91(float32), 0.92(밀집-lm_head 내보내기), 세 개 모두 풀이 핀 고정되고 마지막 둘은 prefill 청크도 1024·512로 줄임, EAGLE은 0.93(bfloat16), 0.94(float32), 추측 없음은 0.90. 드래프트 모델과 함께 float32를 쓸 수 있는지는 lm_head에 달려 있어요: BF16-헤드 내보내기에서는 DSpark와 DFlash2 모두 회색 처리되는데, 밀집 헤드의 ~3.2 GB가 prefill 그래프 캡처를 통과하는 fp32 상태 풀을 남기지 않기 때문이에요. FP4-헤드 내보내기는 그 여유를 되찾아요 — DSpark는 --mamba-full-memory-ratio 10으로 균형 값을 오버라이드해 0.91에서, DFlash2 High-Throughput은 0.895에서 서빙하고, DFlash2 Low-Latency만 손이 닿지 않으며, 거기서 다섯 개 fp32 슬롯과 요청 전체의 KV가 공존하지 못해요. 그럼에도 bfloat16은 더 빠른 선택이에요: DFlash2가 수용 길이 4.29에서 4.92 ms 중간 TPOT을 게시하는데, 이 카드에서 가장 좋은 결과예요.
  • 하드웨어 맞춤: FP8 가중치 ~28.5GB(32GB 카드에서 bs≤2를 넘어서는 서빙 불가); NVFP4 가중치 ~16.5GB(RTX 5090급 GPU에 권장).
  • --mamba-radix-cache-strategy extra_buffer_lazy는 정확도 손실 없이 요청당 상태 비용을 5개 슬롯에서 4개로 낮춰요. 작은 VRAM 카드(RTX 5090 32GB)에서 상태 풀은 KV보다 훨씬 먼저 동시성을 제한해요 — S를 낮추는 걸 선호하세요(lazy 전략, 또는 S=1용 --disable-radix-cache). 계산기가 새 S에 대한 비율을 다시 도출해요. 균형 비율 자체는 VRAM과 무관해요.
  • --mamba-ssm-dtype: GDN 상태 슬롯은 float32에서 153.9 MB(체크포인트의 선언된 정밀도), bfloat16에서 78.4 MB이므로, bf16은 상태 풀을 대략 절반으로 줄이고 차이를 KV에 넘겨요 — 추측 없는 RTX 5090에서 측정됨, fp32의 68,588 대 bf16에서 97,280 KV 토큰. 32GB 카드에서 구성이 들어맞는지도 결정해요: EAGLE은 fp32에서 --mem-fraction-static 0.94가 필요하지만 bf16에서 0.92. 속도는 단방향 트레이드가 아니에요 — 추측 디코딩으로 fp32가 이길 때도(NVFP4 + EAGLE: 152.9 vs 144.5 tok/s/user) 지 때도 있어요(FP8 + EAGLE: 106.3 vs 116.1). 자신의 양자화로 둘 다 측정하세요. bfloat16을 정확도 게이트로 취급하고 워크로드에서 검증하세요. SM120에서는 두 정밀도 모두 Triton 선형-attn prefill 경로를 실행해요 — FlashInfer GDN prefill fast path는 SM100에서 게이트되며, 검증된 영역은 실제로 bf16 상태 풀이에요 — 그래서 여기서 어떤 dtype도 추가 플래그를 강제하지 않아요. 알아둘 상호작용 하나: --enable-linear-replayssm-spec--mamba-ssm-dtype이 설정되지 않으면 fp32 상태를 자동 선택하고, 명시적 비-fp32 값은 부팅 시 상태-드리프트 경고를 로그해요. SSM dtype 행은 항상 플래그를 명시적으로 방출하므로, bf16 + EAGLE 셀은 그 경고와 함께 실행돼요 — 그 검증에 반영됨.
  • --chunked-prefill-size 2048: 하이브리드 GDN 모델에서 decode 단계가 각 prefill 청크 뒤에 멈춰서고, 8192-토큰 청크는 한 번에 ~600ms씩 멈춰요. 2048은 혼합 부하 아래에서 decode 인터-토큰 지연을 매끄럽게 유지하고 단일-웨이브 TTFT도 개선해요.

3. 에이전트 하네스

에이전트 하네스는 OpenAI-호환 엔드포인트 — 또는 Claude Code의 경우 SGLang의 Anthropic-호환 엔드포인트 — 를 통해 모델을 구동하므로, 세 가지가 맞춰지면 어떤 것이든 동작해요.

파서는 명령에 들어 있어요. 위 모든 레시피는 --reasoning-parser qwen3 --tool-call-parser qwen3_coder를 실어요. 그것이 없으면 하네스는 구조화된 tool_calls 대신 원시 텍스트로 툴 호출을 받기 때문이에요. 따라서 PlaygroundParsers 카드는 옵트-아웃이에요 — 두 칩이 켜진 채 시작하고, 하나를 끄면 해당 플래그가 떨어져요.

qwen3_coder는 이 체크포인트에 맞는 툴-호출 파서예요: 그 chat template은 모델에게 <tool_call></tool_call> 안에 중첩된 내부 <function=…> / <parameter=…> 블록으로 답하라고 지시하며, 그것이 바로 그 파서가 디코드하는 것이에요. Hermes 파서(--tool-call-parser hermes)는 <tool_call> 안의 다른 페이로드 — bare JSON — 를 읽으므로, 플래그를 바꾸지 않고 Hermes-형식 하네스를 이 모델에 겨누면 절대 파싱되지 않는 툴 호출이 생겨요. --reasoning-parser qwen3은 template의 enable_thinking 토글과 일치하며, 기본값으로 켜져 있어요.

엔드포인트와 모델 id. 기본 URL은 http://<host>:30000/v1이에요. 하네스가 보내는 model 문자열은 서버의 --model-path와 같아야 해요 — OpenAI /v1/models 이름이 기본적으로 그것과 같아요 — 하네스 구성을 짧게 유지하려 --served-model-name으로 오버라이드하지 않는 한. 후자는 보통 해둘 가치가 있어요.

SGLang은 또한 Anthropic-호환 /v1/messages를 서빙하며, §3.3이 그것을 사용해요. 각 요청을 OpenAI 형태로 변환하고, 같은 chat-서빙 경로에 넘기고, 응답을 다시 변환해요 — 그래서 위 파서 플래그가 동일하게 적용돼요.

인증. --api-key는 기본적으로 설정되지 않으므로 서버가 인증 없는 요청을 받아들여요. 키를 고집하는 하네스는 아무 플레이스홀더나 보낼 수 있어요. 엔드포인트가 localhost를 넘어 도달 가능하면 서버에 --api-key를 설정하세요.

3.1 OpenCode

OpenCodeopencode.json의 provider 항목을 통해 자체 호스팅 엔드포인트에 도달해요.

SGLang을 OpenCode provider로 등록하기

자격 증명을 먼저 저장하세요 — Other를 고르고, provider에 id를 주고, 서버에 --api-key가 없으면 아무 플레이스홀더를 넣으세요:

opencode
/connect

그다음 opencode.json에서 provider를 선언하세요:

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "sglang": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "SGLang (Qwen3.8-27B)",
      "options": {
        "baseURL": "http://localhost:30000/v1"
      },
      "models": {
        "RadixArk/Qwen3.8-27B-NVFP4": {
          "name": "Qwen3.8-27B NVFP4"
        }
      }
    }
  }
}

npm은 전송을 선택해요 — @ai-sdk/openai-compatible는 평범한 OpenAI-형상 엔드포인트용이에요. apiKey는 선택이며 리터럴이 아니라 "{env:VAR_NAME}" 참조를 받아요. models 키는 선 위에 보내지는 id이므로 서빙된 모델 이름과 일치해야 해요. /models로 확인하세요.

3.2 Pi

Pi(@earendil-works/pi-coding-agent)는 설정 파일이 아니라 확장에서 provider를 등록해요.

SGLang을 Pi provider로 등록하기

pi.registerProvider("sglang", {
  baseUrl: "http://localhost:30000/v1",
  api: "openai-completions",
  apiKey: "$SGLANG_API_KEY",
  models: [
    {
      id: "RadixArk/Qwen3.8-27B-NVFP4",
      name: "Qwen3.8-27B",
      reasoning: true,
      input: ["text", "image"],
      cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
      contextWindow: 262144,
      maxTokens: 32768,
    },
  ],
});

api: "openai-completions"가 OpenAI-호환 전송을 선택하고, apiKey는 리터럴이 아니라 $ENV_VAR 참조를 받아요. contextWindow는 체크포인트의 네이티브 262,144이며, maxTokens는 턴당 원하는 출력 상한으로 설정하세요. pi --list-models로 등록을 확인하세요.

3.3 Claude Code

Claude Code는 Anthropic API를 말하므로, OpenAI 엔드포인트가 아니라 SGLang의 /v1/messages를 겨눠요.

Warning: Anthropic은 게이트웨이를 통해 Claude Code를 비-Claude 모델로 라우팅하는 것을 지원하지 않는다고 문서화해요. 아래 배선은 SGLang이 Anthropic 메시지 형식을 구현하기 때문에 동작하지만, Claude Code가 테스트되는 범위 밖이에요 — 최신 Claude Code 기능이 저하되거나 실패할 것으로 예상하세요.

Claude Code를 SGLang에 겨누기

ANTHROPIC_BASE_URL은 서버 오리진이에요 — Claude Code가 /v1/messages를 스스로 붙이므로 /v1 접미사를 빼 두세요:

export ANTHROPIC_BASE_URL=http://localhost:30000
export ANTHROPIC_AUTH_TOKEN=placeholder

두 자격 증명 변수는 서로 다른 헤더로 나가요: ANTHROPIC_AUTH_TOKENAuthorization: Bearer …로, ANTHROPIC_API_KEYx-api-key로 나가요. 둘 중 하나가 --api-key 없이 시작된 서버를 만족해요. --api-key가 설정되면 서버가 읽는 헤더와 일치하는 변수를 고르세요. 자격 증명 변수는 그 세션에서 저장된 claude.ai 로그인보다 우선해요.

같은 쌍은 설정 파일에도 살 수 있는데, 이는 쉘을 가로질러 지속되고 쉘 내보내기보다 이겨요:

{
  "env": {
    "ANTHROPIC_BASE_URL": "http://localhost:30000",
    "ANTHROPIC_AUTH_TOKEN": "placeholder"
  }
}

Claude Code에서 /status를 실행해 세션이 어떤 베이스 URL과 자격 증명 소스를 잡았는지 확인하세요.

3.4 Hermes Agent

Hermes Agent(Nous Research, MIT)는 설정 마법사 또는 설정 파일을 통해 자체 호스팅 엔드포인트를 선택해요.

Hermes Agent를 SGLang에 겨누기

hermes model
# choose "Custom endpoint (self-hosted / VLLM / etc.)", then enter the
# base URL, an API key (blank for a local server) and the model name

동등하게 ~/.hermes/config.yaml에서:

model:
  default: RadixArk/Qwen3.8-27B-NVFP4
  provider: custom
  base_url: http://localhost:30000/v1
  api_key: ""
  context_length: 262144

여러 엔드포인트를 동시에 쓰려면 providers: 아래에 선언하고 세션 중 /model custom:<name>으로 전환하세요:

providers:
  workstation:
    api: http://localhost:30000/v1
  server:
    api: https://gpu-host.internal:30000/v1
    key_env: SGLANG_API_KEY

더 알아보기 (Learn more)