Granite 4.2
Granite 4.2
Granite 4.2은 IBM이 만든 dense decoder-only 언어 모델 제품군으로, 3B·8B·30B 세 가지 체크포인트를 제공해요. 각 체크포인트는 BF16 가중치를 사용하고 구성된 컨텍스트 길이는 131,072 토큰이며, chat template을 통해 기본 thinking(default thinking)·non-thinking·low-effort thinking·구조화된 tool call을 모두 지원해요. 저장소들은 Apache-2.0 라이선스를 선언하고 있어요.
출처: 문서
본문
1. Model introduction
Granite 4.2는 IBM의 dense decoder-only 언어 모델 제품군으로 3B, 8B, 30B 체크포인트를 제공해요. 각 체크포인트는 BF16 가중치를 사용하고 구성된 컨텍스트 길이가 131,072 토큰이며, chat template을 통해 default thinking, non-thinking, low-effort thinking, 그리고 구조화된 tool call을 지원해요. 저장소들은 Apache-2.0 라이선스를 선언하고 있어요.
| Variant | Total params | Position in family |
|---|---|---|
| Granite 4.2 3B | 3B | Smallest checkpoint |
| Granite 4.2 8B | 8B | Mid-size checkpoint |
| Granite 4.2 30B | 30B | Largest checkpoint |
권장 생성 설정: IBM은 일반 채팅·추론·tool calling에서 temperature=1.0과 top_p=0.95를 권장해요. 릴리스 체크포인트는 이 값들을 generation_config.json에 담아 배포하며, 명시적으로 지정하고 싶다면 요청마다 함께 보내면 돼요.
리소스: Granite 4.2 3B · Granite 4.2 8B · Granite 4.2 30B.
2. Configuration tips
- Thinking은 기본으로 활성화돼요. 바로 답을 얻고 싶다면
chat_template_kwargs.enable_thinking을false로 설정해요. 더 짧은 추론 과정을 원한다면enable_thinking과low_effort를true로 설정해요. - Thinking에 충분한 토큰을 주세요.
temperature=1.0에서 기본 thinking 모드는 다단계 문제에서 1,000 토큰을 넘길 수 있어요. thinking 요청에는 답이 잘리지 않도록max_tokens를 최소 2,048로 설정해요. - Reasoning parser.
--reasoning-parser auto로 시작하면 이 체크포인트들에서nemotron_3로 해석되어, OpenAI 호환 응답이 추론을message.reasoning_content로, 답을message.content로 분리해줘요. parser 플래그가 없으면 reasoning 마크업이message.content안에 인라인으로 남아요. - Tool-call parser.
--tool-call-parser auto로 시작하면 이 체크포인트들에서qwen3_coder로 해석되어 tool 요청이message.tool_calls로 반환돼요. 없으면 raw<tool_call>마크업이message.content에 남아요. - 단일 GPU 크기 설계. 세 BF16 체크포인트 모두 H200 한 대와 B200 한 대에서
--tp 1 --mem-fraction-static 0.8로 로드되고 채팅 요청을 완료했어요. 새 토폴로지를 검증한 후에만 TP를 높이세요. - 이미지 선택. 검증된 경로는
lmsysorg/sglang:dev를 사용해요. 검증 중 테스트된 안정 이미지는 모델 로딩 전에 호환되지 않는 의존성 세트를 가졌기 때문에, 더 새로운 태그 릴리스가 확인될 때까지 레시피의 이미지를 사용하세요.
3. Advanced usage
아래 출력은 검증된 서버에서 Granite 4.2 3B를 캡처한 그대로의 결과예요. 샘플링은 확률적이라 같은 요청을 반복해도 다른 문구가 나올 수 있어요.
3.1 Thinking modes
nemotron_3 reasoning parser는 reasoning과 최종 콘텐츠를 별도 필드로 유지해요. Granite 4.2는 세 가지 chat-template 모드를 지원해요: default thinking, non-thinking, low-effort thinking.
from openai import OpenAI
client = OpenAI(base_url="http://localhost:30000/v1", api_key="EMPTY")
model = "ibm-granite/granite-4.2-3b"
modes = {
"thinking": {"enable_thinking": True},
"non-thinking": {"enable_thinking": False},
"low-effort": {"enable_thinking": True, "low_effort": True},
}
for name, chat_template_kwargs in modes.items():
response = client.chat.completions.create(
model=model,
messages=[
{"role": "user", "content": "What is 17 * 23? Answer briefly."}
],
extra_body={"chat_template_kwargs": chat_template_kwargs},
)
message = response.choices[0].message
print(f"[{name}]")
print("Reasoning:", getattr(message, "reasoning_content", None))
print("Answer:", message.content)
[thinking]
Reasoning: Okay, the user asked "What is 17 * 23? Answer briefly." I need to calculate 17 multiplied by 23.
Let me do the multiplication. 17 times 23.
I can break it down: 17 * 20 = 340, and 17 * 3 = 51. Then add them: 340 + 51 = 391.
Alternatively, 23 * 17: 23*10=230, 23*7=161, 230+161=391. Same result.
So the answer is 391.
The user wants a brief answer, so just state the number.
Answer:
391
[non-thinking]
Reasoning: None
Answer: 391
[low-effort]
Reasoning: Compute 17*23 = 17*20=340, plus 17*3=51 => 391.
Answer:
391
3.2 Tool calling
qwen3_coder parser는 모델의 tool 마크업을 OpenAI 호환 구조화 호출로 변환해요.
from openai import OpenAI
client = OpenAI(base_url="http://localhost:30000/v1", api_key="EMPTY")
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "The city name"},
},
"required": ["city"],
},
},
}]
response = client.chat.completions.create(
model="ibm-granite/granite-4.2-3b",
messages=[{"role": "user", "content": "What is the weather in Boston right now?"}],
tools=tools,
tool_choice="auto",
)
choice = response.choices[0]
message = choice.message
print("Reasoning:", getattr(message, "reasoning_content", None))
print("Content:", message.content)
for call in message.tool_calls or []:
print("Tool:", call.function.name)
print("Arguments:", call.function.arguments)
print("Finish reason:", choice.finish_reason)
Reasoning: Okay, the user is asking for the weather in Boston right now. I need to use the available tool called get_weather. The tool requires the city parameter. Since the user specified Boston, I'll call get_weather with city set to Boston.
Content: None
Tool: get_weather
Arguments: {"city": "Boston"}
Finish reason: tool_calls