GLM-4.6

GLM-4.6

이 문서는 Zhipu AI가 개발한 강력한 언어 모델인 GLM-4.6을 SGLang으로 배포하고 호출하는 방법을 설명해요. 추론, 함수 호출, 멀티모달 이해에 있어 고급 능력을 갖추고 있어요. GLM 시리즈의 최신 버전으로서 실제 코딩, 장문 맥락 처리, 추론, 검색, 쓰기, 에이전트 애플리케이션 등 여러 영역에서 전방위 개선을 달성했어요. 원문 페이지에는 하드웨어 플랫폼과 배포 전략을 골라 명령을 자동 생성해 주는 대화형 선택기가 포함되어 있어요.

출처: 문서

본문

1. 모델 소개

GLM-4.6은 Zhipu AI가 개발한 강력한 언어 모델로, 추론, 함수 호출, 멀티모달 이해에 있어 고급 능력을 갖추고 있어요.

GLM 시리즈의 최신 버전으로서, GLM-4.6은 실제 코딩, 장문 맥락 처리, 추론, 검색, 쓰기, 에이전트 애플리케이션을 포함한 여러 영역에서 전방위 개선을 달성해요. 세부 내용은 다음과 같아요:

  • 더 긴 컨텍스트 윈도우 (Longer context window): 컨텍스트 윈도우가 128K에서 200K 토큰으로 확장되어, 더 복잡한 에이전트 작업을 처리할 수 있어요.
  • 우수한 코딩 성능 (Superior coding performance): 코드 벤치마크에서 더 높은 점수를 달성하고 Claude Code, Cline, Roo Code, Kilo Code 같은 애플리케이션에서 더 나은 실제 성능을 보여주며, 시각적으로 세련된 프론트엔드 페이지 생성 개선을 포함해요.
  • 고급 추론 (Advanced reasoning): GLM-4.6은 추론 성능의 뚜렷한 개선을 보여주고 추론 중 도구 사용을 지원해 전반적인 능력이 더 강해져요.
  • 더 유능한 에이전트 (More capable agents): GLM-4.6은 도구 사용 및 검색 기반 에이전트에서 더 강한 성능을 보이며, 에이전트 프레임워크 내에서 더 효과적으로 통합돼요.
  • 정제된 쓰기 (Refined writing): 스타일과 가독성에서 인간 선호도에 더 잘 맞고, 역할극 시나리오에서 더 자연스럽게 동작해요.

자세한 내용은 공식 GLM-4.6 문서를 참고하세요.

2. SGLang 설치

SGLang은 여러 설치 방법을 제공해요. 하드웨어 플랫폼과 요구 사항에 가장 적합한 설치 방법을 선택할 수 있어요.

설치 지침은 공식 SGLang 설치 가이드를 참고하세요.

3. 모델 배포

이 섹션은 서로 다른 하드웨어 플랫폼과 사용 사례에 최적화된 배포 설정을 제공해요.

3.1 기본 설정

대화형 명령 생성기 (Interactive Command Generator): 아래 설정 선택기를 사용해 하드웨어 플랫폼, 양자화 방법, 배포 전략, 사고 능력에 맞는 배포 명령을 자동으로 생성할 수 있어요. (대화형 위젯은 원문 페이지에서 동작하므로, 기본 설정 기준 명령은 다음과 같아요.)

python -m sglang.launch_server \
  --model zai-org/GLM-4.6 \
  --tp 8

3.2 설정 팁

  • EAGLE 추측 디코딩: GLM-4.5/4.6에서 지원돼요. --speculative-algorithm EAGLE --speculative-num-steps 3 --speculative-eagle-topk 1 --speculative-num-draft-tokens 4를 추가하세요. spec-v2 overlap 스케줄러는 기본적으로 활성화되며, 비활성화하려면 --disable-overlap-schedule을 전달하세요.
  • 사고 예산 (Thinking Budget): --enable-custom-logit-processor 플래그를 사용하고 요청에서 Glm4MoeThinkingBudgetLogitProcessor를 전달해 모델의 사고 토큰 수를 제한하세요(4.2.3절 참고).

4. 모델 호출

4.1 기본 사용법

기본 API 사용법과 요청 예시는 다음을 참고하세요:

4.2 고급 사용법

4.2.1 추론 파서 (Reasoning Parser)

GLM-4.6은 기본적으로 Thinking 모드를 지원해요. 배포 중 reasoning parser를 활성화해 thinking 섹션과 content 섹션을 분리하세요:

python -m sglang.launch_server \
  --model zai-org/GLM-4.6 \
  --reasoning-parser glm45 \
  --tp 8 \
  --host 0.0.0.0 \
  --port 8000

사고 과정이 포함된 스트리밍:

from openai import OpenAI

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

# Enable streaming to see the thinking process in real-time
response = client.chat.completions.create(
    model="zai-org/GLM-4.6",
    messages=[
        {"role": "user", "content": "Solve this problem step by step: What is 15% of 240?"}
    ],
    temperature=0.7,
    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 =================
To solve this problem, I need to calculate 15% of 240.
Step 1: Convert 15% to decimal: 15% = 0.15
Step 2: Multiply 240 by 0.15
Step 3: 240 × 0.15 = 36
=============== Content =================

The answer is 36. To find 15% of 240, we multiply 240 by 0.15, which equals 36.

참고: reasoning parser는 모델의 단계별 사고 과정을 캡처해 모델이 결론에 도달하는 방식을 볼 수 있게 해줘요.

4.2.2 도구 호출 (Tool Calling)

모델별 파서 이름: GLM-4.5와 GLM-4.6은 --tool-call-parser glm45을 사용해요. GLM-4.7과 GLM-4.7-Flash는 --tool-call-parser glm47을 사용해요. 모든 GLM 모델은 세대와 무관하게 --reasoning-parser glm45를 사용해요.

GLM-4.6은 도구 호출 기능을 지원해요. tool call parser를 활성화하세요:

python -m sglang.launch_server \
  --model zai-org/GLM-4.6 \
  --reasoning-parser glm45 \
  --tool-call-parser glm45 \
  --tp 8 \
  --host 0.0.0.0 \
  --port 8000

Python 예시 (사고 과정 포함):

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/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-4.6",
    messages=[
        {"role": "user", "content": "What's the weather in Beijing?"}
    ],
    tools=tools,
    temperature=0.7,
    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 about the weather in Beijing. I need to use the get_weather function to retrieve this information.
I should call the function with location="Beijing".
=============== Content =================

🔧 Tool Call: get_weather
   Arguments: {"location": "Beijing", "unit": "celsius"}

참고:

  • reasoning parser는 모델이 도구를 어떻게 사용하기로 결정하는지 보여줘요
  • 도구 호출은 함수 이름과 인자로 명확하게 표시돼요
  • 그런 다음 함수를 실행하고 결과를 다시 보내 대화를 이어갈 수 있어요

도구 호출 결과 처리:

# After getting the tool call, execute the function
def get_weather(location, unit="celsius"):
    # Your actual weather API call here
    return f"The weather in {location} is 22°{unit[0].upper()} and sunny."

# Send tool result back to the model
messages = [
    {"role": "user", "content": "What's the weather in Beijing?"},
    {
        "role": "assistant",
        "content": None,
        "tool_calls": [{
            "id": "call_123",
            "type": "function",
            "function": {
                "name": "get_weather",
                "arguments": '{"location": "Beijing", "unit": "celsius"}'
            }
        }]
    },
    {
        "role": "tool",
        "tool_call_id": "call_123",
        "content": get_weather("Beijing", "celsius")
    }
]

final_response = client.chat.completions.create(
    model="zai-org/GLM-4.6",
    messages=messages,
    temperature=0.7
)

print(final_response.choices[0].message.content)
# Output: "The weather in Beijing is currently 22°C and sunny."

4.2.3 사고 예산 (Thinking Budget)

CustomLogitProcessor로 사고 토큰 수를 제한하세요. --enable-custom-logit-processor로 실행하세요:

import openai
from sglang.srt.sampling.custom_logit_processor import Glm4MoeThinkingBudgetLogitProcessor

client = openai.Client(base_url="http://127.0.0.1:30000/v1", api_key="*")
response = client.chat.completions.create(
    model="zai-org/GLM-4.6",
    messages=[{"role": "user", "content": "Is Paris the Capital of France?"}],
    max_tokens=1024,
    extra_body={
        "custom_logit_processor": Glm4MoeThinkingBudgetLogitProcessor().to_str(),
        "custom_params": {"thinking_budget": 512},
    },
)
print(response)

5. 벤치마크

이 섹션은 비교 가능한 벤치마크 결과를 위해 산업 표준 설정을 사용해요.

5.1 속도 벤치마크

테스트 환경:

  • 하드웨어: NVIDIA B200 GPU (8x), AMD MI300X (8x), AMD MI325X (8x), AMD MI355X (8x)
  • 모델: GLM-4.6
  • 텐서 병렬화(Tensor Parallelism): 8
  • SGLang 버전: 0.5.6.post1

벤치마크 방법론:

결과가 프레임워크와 하드웨어 플랫폼 전반에서 비교 가능하도록 업계 표준 벤치마크 설정을 사용해요.

5.1.1 표준 테스트 시나리오

세 가지 핵심 시나리오가 실제 사용 패턴을 반영해요:

시나리오 입력 길이 출력 길이 사용 사례
Chat 1K 1K 가장 흔한 대화형 AI 워크로드
Reasoning 1K 8K 장문 생성, 복잡한 추론 작업
Summarization 8K 1K 문서 요약, RAG 검색

5.1.2 동시성 수준

각 시나리오를 세 가지 동시성 수준에서 테스트해 처리량과 지연 시간의 트레이드오프(파레토 프론티어)를 포착하세요:

  • 낮은 동시성 (Low Concurrency): --max-concurrency 1 (지연 시간 최적화)
  • 중간 동시성 (Medium Concurrency): --max-concurrency 16 (균형)
  • 높은 동시성 (High Concurrency): --max-concurrency 100 (처리량 최적화)

5.1.3 프롬프트 수

각 동시성 수준에 대해 num_prompts를 구성해 현실적인 사용자 부하를 시뮬레이션하세요:

  • 빠른 테스트 (Quick Test): num_prompts = concurrency × 1 (최소 테스트)
  • 권장 (Recommended): num_prompts = concurrency × 5 (표준 벤치마크)
  • 안정적 측정 (Stable Measurements): num_prompts = concurrency × 10 (프로덕션 등급)

5.1.4 벤치마크 명령

시나리오 1: Chat (1K/1K) - 가장 중요

  • 모델 배포
python -m sglang.launch_server \
  --model zai-org/GLM-4.6 \
  --tp 8
  • 낮은 동시성 (지연 시간 최적화)
python -m sglang.bench_serving \
  --backend sglang \
  --model zai-org/GLM-4.6 \
  --dataset-name random \
  --random-input-len 1000 \
  --random-output-len 1000 \
  --num-prompts 10 \
  --max-concurrency 1 \
  --request-rate inf
  • 중간 동시성 (균형)
python -m sglang.bench_serving \
  --backend sglang \
  --model zai-org/GLM-4.6 \
  --dataset-name random \
  --random-input-len 1000 \
  --random-output-len 1000 \
  --num-prompts 80 \
  --max-concurrency 16 \
  --request-rate inf
  • 높은 동시성 (처리량 최적화)
python -m sglang.bench_serving \
  --backend sglang \
  --model zai-org/GLM-4.6 \
  --dataset-name random \
  --random-input-len 1000 \
  --random-output-len 1000 \
  --num-prompts 500 \
  --max-concurrency 100 \
  --request-rate inf

시나리오 2: Reasoning (1K/8K)

  • 낮은 동시성
python -m sglang.bench_serving \
  --backend sglang \
  --model zai-org/GLM-4.6 \
  --dataset-name random \
  --random-input-len 1000 \
  --random-output-len 8000 \
  --num-prompts 10 \
  --max-concurrency 1 \
  --request-rate inf
  • 중간 동시성
python -m sglang.bench_serving \
  --backend sglang \
  --model zai-org/GLM-4.6 \
  --dataset-name random \
  --random-input-len 1000 \
  --random-output-len 8000 \
  --num-prompts 80 \
  --max-concurrency 16 \
  --request-rate inf
  • 높은 동시성
python -m sglang.bench_serving \
  --backend sglang \
  --model zai-org/GLM-4.6 \
  --dataset-name random \
  --random-input-len 1000 \
  --random-output-len 8000 \
  --num-prompts 320 \
  --max-concurrency 64 \
  --request-rate inf

시나리오 3: Summarization (8K/1K)

  • 낮은 동시성
python -m sglang.bench_serving \
  --backend sglang \
  --model zai-org/GLM-4.6 \
  --dataset-name random \
  --random-input-len 8000 \
  --random-output-len 1000 \
  --num-prompts 10 \
  --max-concurrency 1 \
  --request-rate inf
  • 중간 동시성
python -m sglang.bench_serving \
  --backend sglang \
  --model zai-org/GLM-4.6 \
  --dataset-name random \
  --random-input-len 8000 \
  --random-output-len 1000 \
  --num-prompts 80 \
  --max-concurrency 16 \
  --request-rate inf
  • 높은 동시성
python -m sglang.bench_serving \
  --backend sglang \
  --model zai-org/GLM-4.6 \
  --dataset-name random \
  --random-input-len 8000 \
  --random-output-len 1000 \
  --num-prompts 320 \
  --max-concurrency 64 \
  --request-rate inf

5.1.5 결과 이해하기

핵심 지표:

  • 요청 처리량 (Request Throughput, req/s): 초당 처리되는 요청 수
  • 출력 토큰 처리량 (Output Token Throughput, tok/s): 초당 생성되는 총 토큰 수
  • 평균 TTFT (ms): Time to First Token - 응답성을 측정
  • 평균 TPOT (ms): Time Per Output Token - 생성 속도를 측정
  • 평균 ITL (ms): Inter-Token Latency - 스트리밍 일관성을 측정

이 설정들이 중요한 이유:

  • 1K/1K (Chat): 가장 흔한 대화형 AI 워크로드를 나타내요. 대부분의 배포에서 최우선 시나리오예요.
  • 1K/8K (Reasoning): 복잡한 추론, 코드 생성, 상세한 설명에 중요한 장문 생성 능력을 테스트해요.
  • 8K/1K (Summarization): RAG 시스템, 문서 Q&A, 요약 작업에 필수적인 큰 컨텍스트 입력 성능을 평가해요.
  • 가변 동시성 (Variable Concurrency): 파레토 프론티어를 포착해요 — 서로 다른 부하 수준에서 처리량과 지연 시간 간의 최적 트레이드오프. 낮은 동시성은 최상의 지연 시간을, 높은 동시성은 최대 처리량을 보여줘요.

결과 해석:

  • 결과를 하드웨어에 대한 기준 수치와 비교하세요
  • 같은 지연 시간에서 더 높은 처리량 = 더 나은 성능
  • 더 낮은 TTFT = 더 반응성 좋은 사용자 경험
  • 더 낮은 TPOT = 더 빠른 생성 속도

5.2 정확도 벤치마크

표준 벤치마크에서 모델 정확도를 문서화하세요:

5.2.1 GSM8K 벤치마크

  • 벤치마크 명령
python -m sglang.test.few_shot_gsm8k \
  --num-questions 200 \
  --port 30000