Instructions to use Holy-fox/llm-jp-4-33b-thinking-nvfp4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Holy-fox/llm-jp-4-33b-thinking-nvfp4 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Holy-fox/llm-jp-4-33b-thinking-nvfp4") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("Holy-fox/llm-jp-4-33b-thinking-nvfp4") model = AutoModelForCausalLM.from_pretrained("Holy-fox/llm-jp-4-33b-thinking-nvfp4", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Holy-fox/llm-jp-4-33b-thinking-nvfp4 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Holy-fox/llm-jp-4-33b-thinking-nvfp4" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Holy-fox/llm-jp-4-33b-thinking-nvfp4", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/Holy-fox/llm-jp-4-33b-thinking-nvfp4
- SGLang
How to use Holy-fox/llm-jp-4-33b-thinking-nvfp4 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "Holy-fox/llm-jp-4-33b-thinking-nvfp4" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Holy-fox/llm-jp-4-33b-thinking-nvfp4", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "Holy-fox/llm-jp-4-33b-thinking-nvfp4" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Holy-fox/llm-jp-4-33b-thinking-nvfp4", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use Holy-fox/llm-jp-4-33b-thinking-nvfp4 with Docker Model Runner:
docker model run hf.co/Holy-fox/llm-jp-4-33b-thinking-nvfp4
llm-jp-4-33b-thinking-nvfp4
llm-jp/llm-jp-4-33b-thinking を llm-compressor で NVFP4 (W4A4) に量子化したモデルです。
bf16で約62GiBあったモデルが 20.1GiB になり、RTX 5090 (32GB) 1枚で動作します。
RTX 5090・--max-model-len 16384 の実測で、KVキャッシュに 6.09GiB(24,944トークン分)を確保できました。
このモデルはHarmony応答形式を使う thinking モデルです。vLLMで正しく動かすには
--trust-remote-codeと専用のreasoning parserが必要です。 詳細は「vLLMでの使い方」を必ずお読みください。
量子化仕様
| 項目 | 内容 |
|---|---|
| 量子化形式 | NVFP4 (nvfp4-pack-quantized) |
| 重み | FP4 (E2M1) / group size 16 / tensor_group / スケールはFP8 (E4M3) |
| 活性化 | FP4 (E2M1) / group size 16 / 実行時に動的量子化、グローバルスケールはキャリブレーション済み |
| 量子化対象 | 全ての Linear 層 |
| 除外 | lm_head(bf16のまま) |
| アルゴリズム | QuantizationModifier(RTN + 活性化スケールのキャリブレーション) |
| llm-compressor | 0.13.0 |
| compressed-tensors | 0.18.0 |
embed_tokens と lm_head はbf16のまま残しています(それぞれ約2.0GiB)。
動作環境
NVFP4は Blackwell世代 (sm_120以降) のネイティブFP4演算を前提とします。
| 検証GPU | NVIDIA GeForce RTX 5090 (32GB, sm_120) |
| NVIDIA driver | 580.159.03 / CUDA 13.0 |
| vLLM | 0.27.1 |
| カーネル | FlashInfer b12x (SM120向けネイティブNVFP4 GEMM) |
sm_100系 (B100/B200) でも動作します。sm_120未満のGPUではvLLMがMarlinの 重みのみ量子化 (W4A16) にフォールバックするため、動作はしますが本来の速度は出ません。
起動時のログに次の行が出ていれば、ネイティブFP4演算が使われています。
Using FlashInferCutlassNvFp4LinearKernel for NVFP4 GEMM
RTX 5090での実測値(--max-model-len 16384、単一リクエスト):
| 項目 | 実測 |
|---|---|
| モデルサイズ | 20.1 GiB |
| 重みロード時間 | 2.4秒 |
| KVキャッシュ | 6.09 GiB (24,944トークン) |
| 生成速度 | 約66 tok/s |
長いコンテキストの同時リクエストを増やしたい場合は --kv-cache-dtype fp8 を付けると
KVキャッシュの容量がおよそ倍になります。
vLLMでの使い方
1. reasoning parser を用意する
llm-jp-4はOpenAI Harmony形式で応答しますが、トークナイザがHarmony公式実装と異なるため、
専用のパーサーが必要です。本リポジトリの vllm_plugin/ に
llm-jp-4-cookbook 由来のファイルを同梱しています。
vllm_plugin/
├── llmjp4_harmony.py # Harmonyトークン列のパーサー
├── llmjp4_reasoning_parser.py # vLLM用 reasoning parser (`llmjp4` として登録)
└── example_cli.py # パーサーを登録してから vllm CLI を起動するラッパー
2. サーバーを起動する
huggingface-cli download Holy-fox/llm-jp-4-33b-thinking-nvfp4 \
--local-dir ./llm-jp-4-33b-thinking-nvfp4
cd ./llm-jp-4-33b-thinking-nvfp4
PYTHONPATH=vllm_plugin python3 vllm_plugin/example_cli.py serve . \
--served-model-name llm-jp-4-33b-thinking \
--reasoning-parser llmjp4 \
--trust-remote-code \
--enable-auto-tool-choice --tool-call-parser hermes \
--max-model-len 16384 \
--gpu-memory-utilization 0.92 \
--host 0.0.0.0 --port 8000
(--enable-auto-tool-choice はOpen WebUI等への対応用です。理由は
「Open WebUI などから使う場合」を参照してください。)
Dockerで動かす場合:
docker run --rm --gpus all -p 8000:8000 --ipc=host --shm-size=16g \
-e PYTHONPATH=/model/vllm_plugin \
-v "$PWD:/model:ro" \
--entrypoint python3 \
vllm/vllm-openai:v0.27.1 \
/model/vllm_plugin/example_cli.py serve /model \
--served-model-name llm-jp-4-33b-thinking \
--reasoning-parser llmjp4 \
--trust-remote-code \
--enable-auto-tool-choice --tool-call-parser hermes \
--max-model-len 16384 \
--gpu-memory-utilization 0.92 \
--host 0.0.0.0 --port 8000
--reasoning-parser llmjp4 を付けずに素の vllm serve を使うと、
<|channel|>analysis などの制御トークンがそのまま応答本文に混ざります。
3. リクエストを送る
必ず
stream: trueを使ってください。 現在のvLLMのインターフェース上の制約で、非ストリーミングでは思考内容(reasoning)と 最終回答(content)を分離できません。これはcookbookにも記載されている既知の制限です。
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "llm-jp-4-33b-thinking",
"messages": [{"role": "user", "content": "二次方程式の解の公式を導出して下さい。"}],
"stream": true,
"max_tokens": 4096,
"temperature": 0.7,
"top_p": 0.9
}'
Python (OpenAIクライアント):
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
stream = client.chat.completions.create(
model="llm-jp-4-33b-thinking",
messages=[{"role": "user", "content": "日本の四季について簡潔に説明してください。"}],
stream=True,
max_tokens=4096,
temperature=0.7,
top_p=0.9,
)
reasoning, content = [], []
for chunk in stream:
delta = chunk.choices[0].delta
if getattr(delta, "reasoning", None):
reasoning.append(delta.reasoning)
if delta.content:
content.append(delta.content)
print("--- 思考過程 (analysis) ---")
print("".join(reasoning))
print("\n--- 最終回答 (final) ---")
print("".join(content))
4. Open WebUI などから使う場合
Open WebUI で Function Calling を Native にしていると tool_choice: "auto" が送られ、
vLLM が次のエラーを返します。
"auto" tool choice requires --enable-auto-tool-choice and --tool-call-parser to be set
サーバー起動時に以下を追加すればエラーは解消し、通常のチャットは問題なく動作します (思考チャンネルの分離にも影響しません)。
--enable-auto-tool-choice --tool-call-parser hermes
これはエラーを回避するための措置で、ツール呼び出し自体は機能しません。 llm-jp-4はHarmonyのcommentaryチャンネルでツールを呼びますが、 vLLM 0.27.1に同梱のツールパーサーはどれもこの形式を解釈できません (gpt-oss用の
openaiパーサーは実体のないスタブです)。 このフラグを付けた状態でツールを渡すと、呼び出しが生のJSONテキストとして本文に出力されます。 ツールを実際に使いたい場合は、Open WebUI側の Function Calling を Default (プロンプトベース)にしてください。
5. 推論の深さ (reasoning effort) を変える
チャットテンプレートは reasoning_effort を受け取ります(low / medium / high、既定は medium)。
OpenAI互換APIからは chat_template_kwargs で指定します。
{
"model": "llm-jp-4-33b-thinking",
"messages": [{"role": "user", "content": "..."}],
"chat_template_kwargs": {"reasoning_effort": "high"},
"stream": true
}
オフライン推論 (vLLMのPython API)
from vllm import LLM, SamplingParams
import sys
sys.path.insert(0, "vllm_plugin")
from llmjp4_harmony import HarmonyMessageParser
llm = LLM(model=".", trust_remote_code=True, max_model_len=16384)
tokenizer = llm.get_tokenizer()
prompt = tokenizer.apply_chat_template(
[{"role": "user", "content": "日本語で自己紹介してください。"}],
tokenize=False,
add_generation_prompt=True,
reasoning_effort="medium",
)
out = llm.generate([prompt], SamplingParams(max_tokens=2048, temperature=0.7, top_p=0.9))
token_ids = out[0].outputs[0].token_ids
# NOTE: out[0].outputs[0].text は使わないでください(空白の扱いが崩れます)。
# 必ずトークナイザ側の decode を通してください。
parser = HarmonyMessageParser(tokenizer)
for msg in parser.iter_messages(token_ids):
if msg.channel and msg.content:
channel = tokenizer.decode(msg.channel.token_ids)
text = tokenizer.decode(msg.content.token_ids)
print(f"[{channel}] {text}")
llm-jp-4を扱う上での注意点
--trust-remote-codeは必須です。 本モデルはllmjp4_tokenizer.py(LlamaTokenizerFastの サブクラス)を同梱しています。これはHarmonyの制御トークンとテキストトークンを分けてデコードし、 SentencePieceの空白まわりの既知の問題 (1, 2) を回避するためのものです。- 生の出力テキストをそのまま使わないでください。 上記の理由から、必ず同梱トークナイザの
decodeを通してください。 eos_tokenは<|endoftext|>ではなく<|return|>(id=2) です。openai-harmonyライブラリでは本モデルをトークナイズできません(語彙が異なります)。
キャリブレーション
キャリブレーションには llm-jp/llm-jp-4-33b-thinking-dpo-data の chosen(選択された)側 のみを使用し、2,046サンプルを抽出しました。
思考過程(CoT)込みのHarmony形式で入力
各サンプルはモデル自身のチャットテンプレートで、学習時と同じ完全なHarmony形式に展開しています。 これにより、最終回答だけでなく analysisチャンネル(思考過程) の活性化統計も取得できます。
<|start|>system<|message|>...<|end|>
<|start|>user<|message|>...<|end|>
<|start|>assistant<|channel|>analysis<|message|>{chosen_analysis}<|end|>
<|start|>assistant<|channel|>final<|message|>{chosen_final}<|return|>
なお、マルチターン会話では過去ターンの思考過程は落としています(推論時のチャットテンプレートの 挙動に合わせるため)。対象ターンのCoTは常に保持しています。
サンプルの内訳
活性化統計が入力空間の一部に偏らないよう、3軸で層化して抽出しました。
| 軸 | 方針 | 結果 |
|---|---|---|
| 推論の深さ | reasoning_low / medium / high を均等に |
各33.3% |
| 言語 | かな・漢字の文字比率でサンプル毎に判定し 日本語:英語 = 6:4 | ja 60.0% / en 40.0% |
| データソース | 14サブセット全てを各バケット内でラウンドロビン | 全14種、各5.2〜10.5% |
14サブセットの内訳は daring_anteater / flan / jaster_v1.4.1 /
llmjp_extraction_wiki_ja_v0.1 / llmjp_extraction_wiki_ja_v0.2 / llmjp_magpie_sft_v1.0 /
logical_math_coding_wizard8x22b / multiturn_calm3 / nemotron_post_v2_stem /
nemotron_post_v3_chat / nemotron_post_v3_if / nemotron_post_v3_math /
random_to_fixed_multiturn_calm3 / synthetic_jp_en_coding です。
コードブロックを含むサンプルは全体の38.0%でした。
系列長の上限は3,072トークン、合計 5,622,914トークン を使用しています。
量子化の実行
33Bをbf16で読むと62GiB必要で32GBのGPUには載らないため、pipeline="sequential" を使い、
重みをCPU RAMに置いてデコーダ層を1層ずつGPUへ載せながら量子化しています。
from llmcompressor import oneshot
from llmcompressor.modifiers.quantization import QuantizationModifier
recipe = QuantizationModifier(targets="Linear", scheme="NVFP4", ignore=["lm_head"])
oneshot(
model=model, # CPU上にbf16でロード
dataset=ds,
recipe=recipe,
pipeline="sequential",
sequential_prefetch=True,
max_seq_length=3072,
num_calibration_samples=2046,
)
実行時間はRTX 5090で約68秒/サブグラフ x 65サブグラフ = 約73分でした(VRAM使用量は約4GB)。
ライセンス
Apache License 2.0(元モデルおよびcookbookに従います)。
謝辞
- LLM-jp / 国立情報学研究所 — 元モデル
llm-jp-4-33b-thinking - llm-jp/llm-jp-4-cookbook (Yusuke Oda) —
vllm_plugin/配下のreasoning parser - vLLM Project — llm-compressor
- Downloads last month
- 89
Model tree for Holy-fox/llm-jp-4-33b-thinking-nvfp4
Base model
llm-jp/llm-jp-4-33b-thinking