GLM-5

GLM-5

GLM-5은 Zhipu AI가 개발한 GLM 시리즈 중 가장 강력한 언어 모델로, 복잡한 시스템 엔지니어링과 장기 지평(long-horizon) 에이전트 작업을 겨냥해요. GLM-4.5의 355B 파라미터(활성 32B)에서 744B 파라미터(활성 40B)로 확장하면서 DeepSeek Sparse Attention (DSA)을 통합해 장문 컨텍스트 용량을 유지하면서 배포 비용을 크게 줄였어요.

사전 학습(28.5T 토큰)과 사후 학습(신형 비동기 RL 인프라인 slime 사용) 양쪽의 발전 덕분에 GLM-4.7 대비 큰 개선을 이뤘고, 오픈소스 모델 중 추론·코딩·에이전트 작업에서 최고 수준의 성능을 달성해요. BF16과 FP8 양자화 변형을 제공하며 MIT 라이선스로 공개되었어요.

이 문서는 SGLang으로 GLM-5를 배포하고, 추론 파서·함수 호출 같은 고급 기능과 벤치마크를 실행하는 방법을 설명해요.

원문 페이지에는 하드웨어 플랫폼, 양자화 방법, 배포 전략 등을 골라 실행할 배포 명령어를 자동으로 만들어 주는 대화형 선택기가 포함되어 있어요. 위키에서는 렌더링되지 않으니, 아래 섹션의 명령어를 직접 참고하면 돼요.

출처: 문서

본문

1. 모델 소개

GLM-5은 Zhipu AI가 개발한 GLM 시리즈 중 가장 강력한 언어 모델로, 복잡한 시스템 엔지니어링과 장기 지평 에이전트 작업을 겨냥해요. GLM-4.5의 355B 파라미터(활성 32B)에서 744B 파라미터(활성 40B)로 확장하면서 DeepSeek Sparse Attention (DSA)을 통합해 장문 컨텍스트 용량을 유지하면서 배포 비용을 크게 줄였어요.

사전 학습(28.5T 토큰)과 사후 학습(신형 비동기 RL 인프라인 slime 사용) 양쪽의 발전 덕분에 GLM-5는 GLM-4.7 대비 큰 개선을 이뤘고, 오픈소스 모델 중 추론·코딩·에이전트 작업에서 최고 수준의 성능을 달성해요.

주요 특징:

  • 시스템 엔지니어링 & 에이전트 작업: 복잡한 시스템 엔지니어링과 장기 지평 에이전트 작업을 위해 설계됨
  • 최고 수준의 성능: 오픈소스 모델 중 추론(HLE, AIME, GPQA), 코딩(SWE-bench, Terminal-Bench), 에이전트 작업(BrowseComp, Vending Bench 2)에서 최고 수준
  • DeepSeek Sparse Attention (DSA): 장문 컨텍스트 용량을 유지하면서 배포 비용을 절감
  • 여러 양자화 형식: 서로 다른 성능/메모리 트레이드오프를 위한 BF16, FP8 변형 제공
  • 추측 디코딩: 더 낮은 지연 시간을 위한 EAGLE 기반 추측 디코딩 지원

제공 모델:

라이선스: MIT

2. SGLang 설치

설치 안내는 공식 SGLang 설치 가이드를 참고하세요.

3. 모델 배포

이 섹션에서는 하드웨어 플랫폼과 사용 사례에 맞게 최적화된 배포 구성을 제공해요.

3.1 기본 구성

대화형 명령 생성기: 아래 구성 선택기를 사용하면 하드웨어 플랫폼·양자화 방법·기능에 맞는 배포 명령을 자동으로 생성할 수 있어요. SGLang은 NVIDIA H100, H200, B200 및 AMD MI300X/MI325X/MI355X GPU에서 GLM-5 서빙을 지원해요.

여기 있는 모든 레시피는 기본 `--dsa-topk-backend sgl-kernel`에서 DSA 인덱서 top-k를 실행해요. 다른 top-k 백엔드 선택은 GLM-5에서 완전히 검증되지 않았어요.

3.2 구성 팁

  • 추측 디코딩(MTP)은 대화형 사용 사례의 지연 시간을 크게 줄일 수 있어요.
  • DP Attention: 높은 동시성에서 더 높은 처리량을 위한 데이터 병렬 어텐션을 활성화해요. 단, DP attention은 낮은 동시성 지연 시간을 높은 동시성 처리량과 맞바꾸는 점을 유의하세요 — 동시 요청이 적고 지연 시간에 민감한 워크로드라면 비활성화해야 해요.
  • --mem-fraction-static 플래그는 최적의 메모리 활용을 위해 권장되며, 하드웨어와 워크로드에 맞게 조정하세요.
  • BF16 모델은 NVIDIA 하드웨어에서 FP8 대비 항상 2배의 GPU가 필요해요.
하드웨어 FP8 BF16
H100 tp=16 tp=32
H200 tp=8 tp=16
B200 tp=8 tp=16
MI300X/MI325X tp=8
MI355X tp=8
  • B200 (FP8): Blackwell에서 최적화된 DSA·MoE 백엔드를 위해 --ep 1 --attention-backend dsa --dsa-decode-backend trtllm --dsa-prefill-backend trtllm --moe-runner-backend flashinfer_trtllm --enable-flashinfer-allreduce-fusion을 사용하세요. FP8 가중치 양자화를 위해 --quantization fp8도 추가하세요.

  • AMD GPU: DSA 어텐션 백엔드를 위해 --dsa-prefill-backend tilelang --dsa-decode-backend tilelang을 사용하세요. --chunked-prefill-size 131072--watchdog-timeout 1200(가중치 로딩 20분)을 추가하세요. EAGLE 추측 디코딩은 AMD의 GLM-5에서 현재 지원되지 않아요.

  • 다른 구성 팁(MTP, DSA 커널, Context Parallel, HiSparse, NVFP4, Index Cache)은 DeepSeek-V3.2 cookbook 페이지를 참고하세요. GLM-5와 DeepSeek-V3.2는 같은 모델 구조를 공유하므로 최적화 기법도 공통이에요.

  • CUDA의 Prefill CP: Zigzag(--cp-strategy zigzag)는 GLM-5에서 임시로 사용할 수 없어요. --dp 1과 함께 --enable-prefill-cp --cp-strategy interleave를 사용하세요.

  • IndexCache 메서드를 활성화하려면 GLM-5-FP8에 --json-model-override-args '{"index_topk_pattern": "FFSFSSSFSSFFFSSSFFFSFSSSSSSFFSFFSFFSSFFFFFFSFFFFFSFFSSSSSSFSFFFSFSSSFSFFSFFSSS"}'를 사용하세요. 이 기능은 이 PR을 통해 지원되며 작은 정확도 손실만 도입돼요. 다만 엄격한 정확도 평가를 실행한다면 이 기능을 활성화하지 않는 것이 좋아요.

4. 모델 호출

다음 명령으로 GLM-5를 배포해요 (H200에서 FP8, 모든 기능 활성화):

sglang serve \
  --model-path zai-org/GLM-5-FP8 \
  --tp 8 \
  --tool-call-parser glm47 \
  --reasoning-parser glm45 \
  --speculative-algorithm EAGLE \
  --speculative-num-steps 3 \
  --speculative-eagle-topk 1 \
  --speculative-num-draft-tokens 4 \
  --enable-flashinfer-allreduce-fusion \
  --mem-fraction-static 0.85 \
  --host 0.0.0.0 \
  --port 30000

4.1 MI300X/MI325X/MI355X (ROCm) 서버 명령

다음 ROCm 명령은 AMD GPU를 위한 추가 옵션이며 위 NVIDIA 지침을 대체하지 않아요.

sglang serve \
  --model-path zai-org/GLM-5 \
  --tp 8 \
  --trust-remote-code \
  --dsa-prefill-backend tilelang \
  --dsa-decode-backend tilelang \
  --chunked-prefill-size 131072 \
  --mem-fraction-static 0.80 \
  --watchdog-timeout 1200 \
  --host 0.0.0.0 \
  --port 30000

4.2 기본 사용법

기본 API 사용법과 요청 예시는 아래를 참고하세요:

4.3 고급 사용법

4.3.1 추론(Reasoning) 파서

GLM-5는 기본적으로 Thinking 모드를 지원해요. 배포 시 추론 파서를 활성화하면 thinking 영역과 content 영역을 분리할 수 있어요. thinking 과정은 스트리밍 응답의 reasoning_content를 통해 반환돼요.

thinking을 비활성화하고 Instruct 모드를 사용하려면 요청 시 chat_template_kwargs를 전달하세요:

  • Thinking 모드 (기본값): 모델이 답변 전에 단계별 추론을 수행해요. 추가 파라미터가 필요 없어요.
  • Instruct 모드 ({"enable_thinking": false}): 모델이 thinking 과정 없이 직접 응답해요.

예시 1: Thinking 모드 (기본값)

Thinking 모드는 기본적으로 활성화되어 있어요. 모델은 답변 전에 단계별로 추론하며, thinking 과정은 reasoning_content로 반환돼요:

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:30000/v1",
    api_key="EMPTY"
)

# Thinking mode is enabled by default, no extra parameters needed
response = client.chat.completions.create(
    model="zai-org/GLM-5-FP8",
    messages=[
        {"role": "user", "content": "Solve this problem step by step: What is 15% of 240?"}
    ],
    max_tokens=2048,
    stream=True
)

# Process the stream
has_thinking = False
has_answer = False
thinking_started = False

for chunk in response:
    if chunk.choices and len(chunk.choices) > 0:
        delta = chunk.choices[0].delta

        # Print thinking process
        if hasattr(delta, 'reasoning_content') and delta.reasoning_content:
            if not thinking_started:
                print("=============== Thinking =================", flush=True)
                thinking_started = True
            has_thinking = True
            print(delta.reasoning_content, end="", flush=True)

        # Print answer content
        if delta.content:
            # Close thinking section and add content header
            if has_thinking and not has_answer:
                print("\n=============== Content =================", flush=True)
                has_answer = True
            print(delta.content, end="", flush=True)

print()

출력 예시:

=============== Thinking =================
The user wants me to solve a math problem: "What is 15% of 240?".

Step 1: Understand the problem. I need to calculate a percentage of a number.
Formula: Percentage × Number = Result.

Step 2: Convert the percentage to a decimal or fraction.
15% = 15/100 or 0.15.

Step 3: Perform the multiplication.
Method A: Decimal multiplication.
0.15 × 240.
Break it down:
10% of 240 = 24.
5% is half of 10%, so 12.
15% = 10% + 5% = 24 + 12 = 36.

Method B: Fraction multiplication.
15/100 × 240.
Simplify 240/100 = 2.4.
15 × 2.4.
10 × 2.4 = 24.
5 × 2.4 = 12.
24 + 12 = 36.

Method C: Direct multiplication.
240 × 0.15.
240 × 0.10 = 24.
240 × 0.05 = 12.
24 + 12 = 36.

Step 4: Final Verification.
Is 36 reasonable?
10% is 24. 20% is 48.
15% is halfway between 10% and 20%.
Halfway between 24 and 48 is 36.
The result is correct.

Step 5: Structure the final response. I will present the calculation clearly, perhaps showing the fractional or decimal method, or the mental math shortcut (10% + 5%).
=============== Content =================
Here is the step-by-step solution:

**Step 1: Convert the percentage to a decimal.**
To convert 15% to a decimal, divide by 100.
$$15\% = \frac{15}{100} = 0.15$$

**Step 2: Multiply the decimal by the number.**
Now, multiply 0.15 by 240.
$$0.15 \times 240$$

**Step 3: Perform the calculation.**
You can break this down to make it easier:
$$0.15 = 0.10 + 0.05$$

*   First, find 10% of 240:
    $$0.10 \times 240 = 24$$
*   Next, find 5% (which is half of 10%):
    $$\frac{24}{2} = 12$$
*   Add the two results together:
    $$24 + 12 = 36$$

**Answer:**
15% of 240 is **36**.

예시 2: Instruct 모드 (Thinking 끄기)

thinking을 비활성화하고 직접 응답을 받으려면 chat_template_kwargs{"enable_thinking": false}를 전달하세요:

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:30000/v1",
    api_key="EMPTY"
)

# Disable thinking mode via chat_template_kwargs
response = client.chat.completions.create(
    model="zai-org/GLM-5-FP8",
    messages=[
        {"role": "user", "content": "What is 15% of 240?"}
    ],
    extra_body={"chat_template_kwargs": {"enable_thinking": False}},
    max_tokens=2048,
    stream=True
)

# In Instruct mode, the model responds directly without reasoning_content
for chunk in response:
    if chunk.choices and len(chunk.choices) > 0:
        delta = chunk.choices[0].delta
        if delta.content:
            print(delta.content, end="", flush=True)

print()

출력 예시:

To find **15% of 240**, follow these steps:

### Step 1: Convert the Percentage to a Decimal
First, convert the percentage to a decimal by dividing by 100.

\[
15\% = \frac{15}{100} = 0.15
\]

### Step 2: Multiply by the Number
Next, multiply the decimal by the number you want to find the percentage of.

\[
0.15 \times 240
\]

### Step 3: Perform the Multiplication
Calculate the multiplication:

\[
0.15 \times 240 = 36
\]

### Final Answer
\[
\boxed{36}
\]

4.3.2 함수 호출(Tool Calling)

GLM-5는 함수 호출 기능을 지원해요. 배포 시 함수 호출 파서를 활성화하세요. Thinking 모드는 기본적으로 켜져 있으며, 함수 호출 요청에서 비활성화하려면 extra_body={"chat_template_kwargs": {"enable_thinking": False}}를 전달하세요.

Python 예시 (Thinking 과정 포함):

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:30000/v1",
    api_key="EMPTY"
)

# Define available tools
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get the current weather for a location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city name"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "Temperature unit"
                    }
                },
                "required": ["location"]
            }
        }
    }
]

# Make request with streaming to see thinking process
response = client.chat.completions.create(
    model="zai-org/GLM-5-FP8",
    messages=[
        {"role": "user", "content": "What's the weather in Beijing?"}
    ],
    tools=tools,
    stream=True
)

# Process streaming response
thinking_started = False
has_thinking = False

for chunk in response:
    if chunk.choices and len(chunk.choices) > 0:
        delta = chunk.choices[0].delta

        # Print thinking process
        if hasattr(delta, 'reasoning_content') and delta.reasoning_content:
            if not thinking_started:
                print("=============== Thinking =================", flush=True)
                thinking_started = True
            has_thinking = True
            print(delta.reasoning_content, end="", flush=True)

        # Print tool calls
        if hasattr(delta, 'tool_calls') and delta.tool_calls:
            # Close thinking section if needed
            if has_thinking and thinking_started:
                print("\n=============== Content =================", flush=True)
                thinking_started = False

            for tool_call in delta.tool_calls:
                if tool_call.function:
                    print(f"Tool Call: {tool_call.function.name}")
                    print(f"   Arguments: {tool_call.function.arguments}")

        # Print content
        if delta.content:
            print(delta.content, end="", flush=True)

print()

출력 예시:

=============== Thinking =================
The user is asking for the weather in Beijing. I have access to a get_weather function that can provide current weather information. Let me check what parameters are required:

- location: required, should be "Beijing"
- unit: optional (not in required array), can be "celsius" or "fahrenheit"

Since the user didn't specify a unit preference and it's optional, I should not ask about it or make up a value. I'll just call the function with the required location parameter.I'll get the current weather in Beijing for you.
=============== Content =================
Tool Call: get_weather
   Arguments:
Tool Call: None
   Arguments: {
Tool Call: None
   Arguments: "location": "Be
Tool Call: None
   Arguments: ijing"
Tool Call: None
   Arguments: }

5. 벤치마크

5.1 속도 벤치마크

테스트 환경:

  • 하드웨어: H200 (8x)
  • 모델: GLM-5-FP8
  • 텐서 병렬화: 8
  • SGLang 버전: commit 947927bdb

5.1.1 지연 시간 벤치마크

python3 -m sglang.bench_serving \
  --backend sglang \
  --model zai-org/GLM-5-FP8 \
  --dataset-name random \
  --random-input-len 1000 \
  --random-output-len 1000 \
  --num-prompts 10 \
  --max-concurrency 1 \
  --request-rate inf
============ Serving Benchmark Result ============
Backend:                                 sglang
Traffic request rate:                    inf
Max request concurrency:                 1
Successful requests:                     10
Benchmark duration (s):                  35.78
Total input tokens:                      6101
Total input text tokens:                 6101
Total generated tokens:                  4220
Total generated tokens (retokenized):    4213
Request throughput (req/s):              0.28
Input token throughput (tok/s):          170.54
Output token throughput (tok/s):         117.96
Peak output token throughput (tok/s):    148.00
Peak concurrent requests:                2
Total token throughput (tok/s):          288.50
Concurrency:                             1.00
Accept length:                           3.48
----------------End-to-End Latency----------------
Mean E2E Latency (ms):                   3576.31
Median E2E Latency (ms):                 2935.97
P90 E2E Latency (ms):                    5908.97
P99 E2E Latency (ms):                    8588.08
---------------Time to First Token----------------
Mean TTFT (ms):                          290.88
Median TTFT (ms):                        282.34
P99 TTFT (ms):                           332.27
-----Time per Output Token (excl. 1st token)------
Mean TPOT (ms):                          7.54
Median TPOT (ms):                        6.97
P99 TPOT (ms):                           9.04
---------------Inter-Token Latency----------------
Mean ITL (ms):                           7.80
Median ITL (ms):                         6.81
P95 ITL (ms):                            13.51
P99 ITL (ms):                            26.99
Max ITL (ms):                            29.50
==================================================

5.1.2 처리량 벤치마크

python3 -m sglang.bench_serving \
  --backend sglang \
  --model zai-org/GLM-5-FP8 \
  --dataset-name random \
  --random-input-len 1000 \
  --random-output-len 1000 \
  --num-prompts 1000 \
  --max-concurrency 100 \
  --request-rate inf
============ Serving Benchmark Result ============
Backend:                                 sglang
Traffic request rate:                    inf
Max request concurrency:                 100
Successful requests:                     1000
Benchmark duration (s):                  411.74
Total input tokens:                      502493
Total input text tokens:                 502493
Total generated tokens:                  500251
Total generated tokens (retokenized):    499614
Request throughput (req/s):              2.43
Input token throughput (tok/s):          1220.41
Output token throughput (tok/s):         1214.97
Peak output token throughput (tok/s):    2648.00
Peak concurrent requests:                105
Total token throughput (tok/s):          2435.38
Concurrency:                             96.30
Accept length:                           3.50
----------------End-to-End Latency----------------
Mean E2E Latency (ms):                   39648.76
Median E2E Latency (ms):                 39058.12
P90 E2E Latency (ms):                    57009.82
P99 E2E Latency (ms):                    68880.33
---------------Time to First Token----------------
Mean TTFT (ms):                          20613.80
Median TTFT (ms):                        21429.21
P99 TTFT (ms):                           29543.17
-----Time per Output Token (excl. 1st token)------
Mean TPOT (ms):                          38.73
Median TPOT (ms):                        36.52
P99 TPOT (ms):                           67.09
---------------Inter-Token Latency----------------
Mean ITL (ms):                           38.13
Median ITL (ms):                         16.57
P95 ITL (ms):                            86.01
P99 ITL (ms):                            164.88
Max ITL (ms):                            1307.02
==================================================

5.2 정확도 벤치마크

아래 정확도 벤치마크 결과는 GLM-5.1과 공유돼요. 글을 쓰는 시점에 GLM-5.1이 별도로 벤치마크되지 않았기 때문이에요. 별도의 GLM-5.1 벤치마크 실행이 계획되어 있어요.

5.2.1 GSM8K 벤치마크

  • 벤치마크 명령
python3 benchmark/gsm8k/bench_sglang.py --port 30000
  • 테스트 결과
Accuracy: 0.955
Invalid: 0.000
Latency: 32.470 s
Output throughput: 642.044 token/s

5.2.2 MMLU 벤치마크

  • 벤치마크 명령
python3 benchmark/mmlu/bench_sglang.py --port 30000
  • 테스트 결과
subject: abstract_algebra, #q:100, acc: 0.860
subject: anatomy, #q:135, acc: 0.874
subject: astronomy, #q:152, acc: 0.941
subject: business_ethics, #q:100, acc: 0.880
subject: clinical_knowledge, #q:265, acc: 0.932
subject: college_biology, #q:144, acc: 0.972
subject: college_chemistry, #q:100, acc: 0.640
subject: college_computer_science, #q:100, acc: 0.900
subject: college_mathematics, #q:100, acc: 0.810
subject: college_medicine, #q:173, acc: 0.873
subject: college_physics, #q:102, acc: 0.912
subject: computer_security, #q:100, acc: 0.880
subject: conceptual_physics, #q:235, acc: 0.928
subject: econometrics, #q:114, acc: 0.807
subject: electrical_engineering, #q:145, acc: 0.897
subject: elementary_mathematics, #q:378, acc: 0.937
subject: formal_logic, #q:126, acc: 0.778
subject: global_facts, #q:100, acc: 0.710
subject: high_school_biology, #q:310, acc: 0.961
subject: high_school_chemistry, #q:203, acc: 0.847
subject: high_school_computer_science, #q:100, acc: 0.960
subject: high_school_european_history, #q:165, acc: 0.891
subject: high_school_geography, #q:198, acc: 0.960
subject: high_school_government_and_politics, #q:193, acc: 0.984
subject: high_school_macroeconomics, #q:390, acc: 0.923
subject: high_school_mathematics, #q:270, acc: 0.696
subject: high_school_microeconomics, #q:238, acc: 0.962
subject: high_school_physics, #q:151, acc: 0.821
subject: high_school_psychology, #q:545, acc: 0.956
subject: high_school_statistics, #q:216, acc: 0.889
subject: high_school_us_history, #q:204, acc: 0.941
subject: high_school_world_history, #q:237, acc: 0.945
subject: human_aging, #q:223, acc: 0.857
subject: human_sexuality, #q:131, acc: 0.908
subject: international_law, #q:121, acc: 0.934
subject: jurisprudence, #q:108, acc: 0.907
subject: logical_fallacies, #q:163, acc: 0.933
subject: machine_learning, #q:112, acc: 0.830
subject: management, #q:103, acc: 0.942
subject: marketing, #q:234, acc: 0.940
subject: medical_genetics, #q:100, acc: 0.990
subject: miscellaneous, #q:783, acc: 0.959
subject: moral_disputes, #q:346, acc: 0.873
subject: moral_scenarios, #q:895, acc: 0.837
subject: nutrition, #q:306, acc: 0.922
subject: philosophy, #q:311, acc: 0.897
subject: prehistory, #q:324, acc: 0.929
subject: professional_accounting, #q:282, acc: 0.844
subject: professional_law, #q:1534, acc: 0.714
subject: professional_medicine, #q:272, acc: 0.941
subject: professional_psychology, #q:612, acc: 0.913
subject: public_relations, #q:110, acc: 0.791
subject: security_studies, #q:245, acc: 0.878
subject: sociology, #q:201, acc: 0.940
subject: us_foreign_policy, #q:100, acc: 0.920
subject: virology, #q:166, acc: 0.596
subject: world_religions, #q:171, acc: 0.936
Total latency: 165.275
Average accuracy: 0.877

5.3 AMD GPU 벤치마크

5.3.1 GSM8K 벤치마크 (MI325/MI35x)

  • MI325/MI35x 테스트 (GLM-5 BF16, tp=8, TileLang DSA 백엔드)
python3 benchmark/gsm8k/bench_sglang.py --num-questions 200
Accuracy: 0.970
Invalid: 0.000

결과는 AMD nightly CI에서 가져온 거예요. sglang#18911도 참고하세요.

더 알아보기 (Learn more)