llm-jp-4.1-32b-a3b-thinking-Ablitrated
llm-jp/llm-jp-4.1-32b-a3b-thinking を abliteration(拒否・迂回の除去)したモデルです。
- 重み: 層 16 expert 127
down_projに rank-1 additive (dose −5, sigma 1.86) を焼き込み。Runtime hook・条件付き処理は不要。 - 精度: 知識 probe 30 問 29/30、GSM8K 抽出 28/30、ツールコール 5/5、偽前提 10 問で 7/10 を正しく訂正(親は 5/10)。
- アーキテクチャ:
Qwen3MoeForCausalLM、32 層 / MoE active 3.3B / MoE 総 32B、vocab 196608、chat_templateはllm-jp-harmony-v1。
llama.cpp で動かす(GGUF)
使うファイルを選ぶ:
| ファイル | サイズ | 用途 |
|---|---|---|
ljp41-ablit-L16-Q5mix.gguf | 20.7 GiB | 推奨。量子化による劣化が実質ゼロで、24GB クラスの GPU に収まる |
ljp41-ablit-L16-nvf4-W4A8.gguf | 19.9 GiB | Blackwell (RTX 50 系 / compute 12.0) 向け。fp4 重み × int8 activations の native mma kernel |
ljp41-ablit-L16-bf16.gguf | 59.9 GiB | 量子化なしの参照用。約 60GiB の VRAM/RAM が必要 |
# サーバー起動(推奨: --jinja で chat template 適用)
llama-server -m ljp41-ablit-L16-Q5mix.gguf -ngl 99 -c 4096 --port 8905 --jinja
# BF16 版(量子化なし・参照用)
llama-server -m ljp41-ablit-L16-bf16.gguf -ngl 99 -c 4096 --port 8905 --jinja
# NVFP4 版
llama-server -m ljp41-ablit-L16-nvf4-W4A8.gguf -ngl 99 -c 4096 --port 8905 --no-webui --jinja
# ① /completion で raw prompt を直接入力(最も安定)
curl -s http://127.0.0.1:8905/completion \
-H "Content-Type: application/json" \
-d '{
"prompt": "<|start|>system<|message|>You are LLM-jp-4, a large language model trained by LLM-jp.\nKnowledge cutoff: 2025-12\nCurrent date: <DATE>\n\nReasoning: medium\n\n# Valid channels: analysis, commentary, final. Channel must be included for every message.<|end|><|start|>user<|message|>17×23 はいくつか。数字だけ。<|end|><|start|>assistant<|channel|> final<|message|>",
"n_predict": 128, "temperature": 0, "stop": ["<|end|>"]
}'
# ② chat template を client 側で render して /completion に投げる(お勧め)
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("Hikari07jp/llm-jp-4.1-32b-a3b-thinking-Ablitrated",
trust_remote_code=True)
prompt = tok.apply_chat_template([{"role": "user", "content": "..."}], tokenize=False, add_generation_prompt=True)
# → 推論は行わず text で /completion に POST、レスポンスの `content` をそのまま解析する(skip_special_tokens=False 相当の raw が返ってくる)
# → final 部を split する:
text = response["content"]
final = text.rsplit("<|channel|> final<|message|>", 1)[-1].split("<|end|>")[0]
# ③ /v1/chat/completions は動くが、下記の「注意」にある通り
# 一部の応答で openai 互換 layer の harmony parse に 500 が出ます(内容は失われていない、後述)。
リポジトリの中身
| ファイル | 説明 |
|---|---|
model-0*.safetensors(13 shard, 約 60GB) | Abliterated BF16 本体 |
ljp41-ablit-L16-Q5mix.gguf(20.7GiB) | llama.cpp 用の推奨量子化。expert gate/up=q5_K + down=q5_0 の混成(held-out ppl +0.011) |
ljp41-ablit-L16-nvf4-W4A8.gguf(19.9GiB) | llama.cpp 用 NVFP4 W4A8(Blackwell native fp4 重み + Q8 activations、held-out ppl +0.153) |
ljp41-ablit-L16-bf16.gguf(59.9GiB) | llama.cpp 用 BF16 GGUF。量子化前の参照(ppl の基準)で、上の GGUF 群はすべてこのファイルから生成 |
abliteration_meta.json | 焼き込み recipe と edited_tensors 一覧 |
Transformers で動かす
Tokenizer は trust_remote_code 付きで動きます(llmjp4_tokenizer.py / llmjp4_harmony.py を同梱)。
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
m = "Hikari07jp/llm-jp-4.1-32b-a3b-thinking-Ablitrated"
tok = AutoTokenizer.from_pretrained(m, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
m,
trust_remote_code=True,
torch_dtype=torch.bfloat16,
device_map="auto",
)
prompt = tok.apply_chat_template(
[{"role": "user", "content": "日本の四季について短い随筆を書いて。"}],
tokenize=False,
add_generation_prompt=True,
reasoning_effort="low",
)
out = model.generate(
**tok(prompt, return_tensors="pt").to(model.device),
max_new_tokens=512,
do_sample=False,
)
print(tok.decode(out[0][tok(prompt).input_ids.shape[-1]:], skip_special_tokens=False))
skip_special_tokens=False で返り値に <|channel|>analysis ... <|channel|>final ... が入るので、
final の部分だけを UI に渡すのが基本です(後述の Harmony プロトコル注意点参照)。
注意点 / 既知の非互換(本モデルや量子化側ではなく llama.cpp 側)
/v1/chat/completionsの検証: このモデルは<|start|>の直後に space token (id 609) を生成する(本来assistantで始まる)。これは normalization で 先頭に▁を prepend する llm-jp-4.1 の tokenizer 学習分布由来。 llama.cpp の Harmony parser が<|start|>assistantを strict に見るので、この space token を検知してFailed to parse input at pos 18型の 500 を返すことがある。- 生成自体は完了しており、
/v1/chat/completionsの戻り値のエラーメッセージ JSON に<|channel|> final<|message|>以後の本文が含まれています (client 側で regexp で取り出せば正しく回答を拾えます)。量子化前後でこの挙動は同一です。 - 対応済み: 上記の
/completion(raw prompt) or client-side template render +/completionをお勧めします。 /v1/chat/completionsをそれでも使いたい場合、(a)--jinjaをつけないでllama-serverを起動し、 (b) 「manual contentで special-token stream で final channel だけ抽出」のパッチを入れるのが最安定。
- 生成自体は完了しており、
llama-completionに同梱の default prompt 形式 で special token が壊れる場合がある(-p直接 prompt だと置かず、上記の raw prompt を/completionで POST する形式に統一してください)。- OpenAI-compatible clients (LangChain / ollama / etc.) と組み合わせる場合、
Failed to parse input at pos 18が出た場合 は raw stream のcontentを最後の<|channel|> finalから切って用いる(上記 client-side render パターン)。
量子化で消える情報はあるか
- ハルシネーションやラベル付けの曖昧さは増えていません。負傷系マーカー(血/死体...)は 0。
- このモデル固有の挙動(
<|channel|>finalでいきなり final に飛ぶ)は親・bf16 焼き込み・Q5mix・NVFP4 のどれでも同じです。 - 本モデルは runtime hook / 条件付き処理を一切使わない素の重みのみ で動作します。 推論の実装 (Python transformers / llama.cpp / その他のランタイム) 依存を生まない設計で、 ここに載せた実測値は すべて hook なしの素の推論で測定しています。
量子化の品質(実測)
能力面(llama.cpp 経由、temp 0):
| 指標 | base | 本モデル・BF16 | NVFP4 W4A8 |
|---|---|---|---|
| 知識 probe 30 問 | 28/30 | 29/30 | 29/30 |
| 偽前提 10 問の訂正 | 5/10 | 7/10 | 7/10 |
| ツールコール 5 問 | 5/5 | 5/5 | 5/5 |
| GSM8K 抽出 | 28/30 | 28/30 | 28/30 |
| 負傷系幻覚マーカー | 0 | 0 | 0 |
held-out 日本語 Wikipedia(校正コーパスと記事単位で非重複、150 chunks、n_ctx 1024)の perplexity を、bf16 焼き込み基準の chunk 単位 paired 差分で比較:
| GGUF | サイズ | held-out ppl 差分 vs bf16 |
|---|---|---|
bf16.gguf(量子化なし・参照) | 59.9 GiB | ±0(基準) |
Q5mix.gguf(推奨) | 20.7 GiB | +0.011 ± 0.003 |
nvf4-W4A8.gguf | 19.9 GiB | +0.153 ± 0.004 |
| 参考: 親 llm-jp-4.1 base bf16 | 60 GiB | +0.054 ± 0.002 |
焼き込み自体の能力コストは ゼロ(bf16 焼き込み vs 親 = ±0.05、誤差内)で、
Q5mix の量子化劣化は「親と焼き込みの差」より小さくなっています。
能力面(同一ハーネス、思考予算 512 tokens、client 側 template render + /completion):
| モデル | 知識 30 | ツールコール 5 | GSM8K-30 | GSM8K-100 |
|---|---|---|---|---|
| bf16 焼き込み | 30/30 | 5/5 | 28/30 | 54/100 |
Q5mix | 30/30 | 5/5 | 28/30 | 54/100 |
この粒度では bf16 参考値自体が天井(30/30・28/30・54/100)のため、量子化の差は ppl 側に出ます。
llama-quantize に imatrix を渡し、テンソル型を明示指定して作成しています。
| テンソル | 型 |
|---|---|
ffn_gate_exps / ffn_up_exps | q5_K |
ffn_down_exps | q5_0 |
attn_q / attn_output | q5_K |
attn_k / attn_v | q6_K |
token_embd | q5_K |
output | q6_K |
これ以外のテンソル(router ffn_gate_inp と各 norm)は常に f32 です。
imatrix も作り直しました。旧校正は 181 KiB の単一シーン文書(30 chunks ≒ 30k トークン)で、
ppl 評価にも同じファイルを使っていた(in-domain で循環)ため、Wikipedia-ja + 英語指示 +
GSM8K + harmony ツールコール実トレース + 口語 + 約9% in-domain の広域 2.0 MiB
(--chunks 200, n_ctx 2048 ≒ 410k トークン)に差し替えています。
License
Apache-2.0(ベースモデルに準拠)
Credits
- base: llm-jp/llm-jp-4.1-32b-a3b-thinking
- abliteration: Hikari07jp (2026-09-30)