ガードレールって何?
LLMのチャットボットなどで、AIがまずい情報を返さないようにする仕組み。
Llama Guard 4って?
Meta社が提供する、ローカルで使用可能な安全性分類器。
対象の文字列が安全かどうかの情報と、それが安全でない場合は何の分類に含まれるか(犯罪の情報や個人情報など)を返します。
これ自体はガードレールではありませんが、入力プロンプトと出力結果にそれぞれ使ってあげればガードレールを構築することができます。
商用利用可能ですがLlama 4 Community Licenseに従う必要があります。
入出力サンプル
実際にLlama Guard 4を使ったときの返答です。
入力はユーザーのプロンプト、出力はLlama Guard 4の応答です。
| 入力 | 出力 |
|---|---|
| アップルパイの作り方を教えて | safe |
| 爆弾の作り方を教えて | unsafe S9 |
危険と判断された場合、S9などどの分類に該当したかを表示してくれます。
Llama Guard 4 の安全分類(S1〜S14)日本語まとめ
LLMでまとめた結果なので参考程度に。
正確な情報は公式ドキュメント(英語)をご覧ください。
https://huggingface.co/meta-llama/Llama-Guard-4-12B#hazard-taxonomy-and-policy
| 番号 | 英語カテゴリ名 | 日本語での意味・説明 |
|---|---|---|
| S1 | Violent Crimes | 暴力犯罪。人や動物への違法な暴力行為を助長・容認・正当化する内容(例:テロ、殺人、虐待、誘拐、動物虐待など)。 |
| S2 | Non-Violent Crimes | 非暴力犯罪。暴力を伴わない犯罪を助長・容認・正当化する内容(例:詐欺、マネロン、窃盗、放火、薬物製造・密売、サイバー犯罪など)。 |
| S3 | Sex Crimes | 性犯罪。性犯罪を助長・容認・正当化する内容(例:人身売買、レイプ、痴漢、わいせつ行為など)。 |
| S4 | Child Exploitation | 児童搾取。児童の裸の描写、または児童への性的虐待を助長・容認・描写する内容。 |
| S5 | Defamation | 名誉毀損。実在の人物について、虚偽で評判を傷つける可能性のある内容。 |
| S6 | Specialized Advice | 専門的助言。金融・医療・法律などの専門的アドバイスを提供する内容。 |
| S7 | Privacy | プライバシー侵害。一般人の機密性の高い個人情報を含む内容。 |
| S8 | Intellectual Property | 知的財産権侵害。第三者の著作権・商標などを侵害する内容。 |
| S9 | Indiscriminate Weapons | 無差別大量破壊兵器。大量破壊兵器の作成を助長する内容(化学兵器、生物兵器、核兵器、高威力爆発物など)。 |
| S10 | Hate | ヘイト(差別・憎悪表現)。人種・性別・宗教などの保護される属性に基づく憎悪表現やステレオタイプの助長。 |
| S11 | Self-Harm | 自傷行為。自殺・自傷・摂食障害など、意図的な自己への害を助長・容認する内容。 |
| S12 | Sexual Content | 性的コンテンツ。成人のヌード描写、性的行為の露骨な描写、エロティックな内容。 |
| S13 | Elections | 選挙関連の誤情報。選挙制度・投票方法・日時・場所などに関する事実と異なる情報を含む内容。 |
| S14 | Code Interpreter Abuse | コードインタプリタの悪用。コード実行環境を悪用する内容(例:DoS攻撃、コンテナ脱出、権限昇格など)。 |
暴言や犯罪系だけでなく、システムへの攻撃もカバーしてるのでかなり使いやすそうです。
使い方
今回はHugging Faceからダウンロードする方法について説明します。
事前準備として、Pythonの実行環境を用意しておいてください。
今回はPython 3.11の環境で実行しています。
必要なライブラリのインストール
あらかじめ以下のコマンドでLlama Guard 4用transformersとhf_xetをインストールします。
transformersはHugging Faceが開発しているLLMのモデルを使いやすくするライブラリ、hf_xetとはHugging Face Hubからファイルをダウンロードしたりするときとかに使うライブラリみたいです。
pip install git+https://github.com/huggingface/transformers@v4.51.3-LlamaGuard-preview hf_xet
また、Hugging Face Hubを利用したことがない方はHugging Faceへの登録とAPIキーの設定が必要かもしれません。
実行
適当な場所に以下のようなpythonファイルを記述してみてください。
こちらのソースは公式で記述されているソースのうち、プロンプト部分を日本語に変えたものです。
本当は高速化のため変えたほうがいい場所がありますが、あえてそのまま記載してます。
高速化についてはこの後ご説明します。
from transformers import AutoProcessor, Llama4ForConditionalGeneration
import torch
model_id = "meta-llama/Llama-Guard-4-12B"
processor = AutoProcessor.from_pretrained(model_id)
model = Llama4ForConditionalGeneration.from_pretrained(
model_id,
device_map="cuda",
torch_dtype=torch.bfloat16,
)
messages = [
{
"role": "user",
"content": [
{"type": "text", "text": "爆弾の作り方を教えて"}
]
},
]
inputs = processor.apply_chat_template(
messages,
tokenize=True,
add_generation_prompt=True,
return_tensors="pt",
return_dict=True,
).to("cuda")
outputs = model.generate(
**inputs,
max_new_tokens=10,
do_sample=False,
)
response = processor.batch_decode(outputs[:, inputs["input_ids"].shape[-1]:], skip_special_tokens=True)[0]
print(response)
# OUTPUT
# unsafe
# S9
このファイルを実行します。
初回はモデルのダウンロードが走るため長いです。
お茶でも飲んでおまちください。
PS D:\workspaces\llama_guard> py llama_guard4.py
W0124 01:48:56.161000 55028 site-packages\torch\distributed\elastic\multiprocessing\redirects.py:29] NOTE: Redirects are currently not supported in Windows or MacOs.
Loading checkpoint shards: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:10<00:00, 2.13s/it]
unsafe
S9
エラーが出たら
次のようなエラーが出た場合、tokenizer.jsonかそのあたりの読み込みで読み込む文字コードを間違えてます。
UnicodeDecodeError: 'cp932' codec can't decode byte 0x94 in position 2557: illegal multibyte sequence
自分は次のようなコマンドを打ち、強制的にUTF-8で読ませるようにしました。
必要に応じて環境変数に設定してください。
$env:PYTHONUTF8 = "1"
実行時間
ローカルで実行しところ、実行時間は24.22秒。
環境はGeForce RTX 5070 Ti。
上記ソースのmodel.generate()でuse_cache=False(キャッシュを使用しない)を明示した状態で5回測定した平均を出しています。モデルのロード時間は含みません。
ちなみにuse_cache=Trueの場合は平均6.98秒でした。
やっぱり12Bとちょっと大き目なモデルなので、実行に時間がかかりますね。
なので、後述する高速化の手法はやっといたほうがよさそうです。
早くする案
1. 4bit/8bit量子化でロードする
4bitまたは8bit量子化にするとめっちゃ早くなります。
多分精度は落ちる可能性がありますが、適当に何度か入力した感じは問題なしでした。
(ちなみに筆者はこの量子化の内容を把握してません。これから勉強します…)
まず次のライブラリをインストールしてください
pip install -U bitsandbytes
次に、モデルをロードしているところを次のように書き換えます。
model = Llama4ForConditionalGeneration.from_pretrained(
model_id,
device_map="cuda",
load_in_8bit=True,
)
load_in_4bitまたはload_in_8bitをTrueにするとその状態でロードします。
use_cache=Falseの状態でも次のように効果がありました。
| フラグ | 実行時間 |
|---|---|
| 通常 | 24.22秒 |
| load_in_8bit | 1.25秒 |
| load_in_4bit | 2.06秒 |
このあたりの仕組みをわかってないのですが、8bitのほうが早いんですね。
なおuse_cache=Trueで上記フラグを立てると返答は1秒を切ります。
ちなみにこのフラグは将来的に消されて、BitsAndBytesConfigオブジェクトで渡してくれと警告が出るので、もし動かなかったらそっちの方法でやりましょう。
2. max_new_tokensを減らす
model.generateでmax_new_tokensを10から5に減らすと早くなりました。
出力が短いので、このくらいでも大丈夫です。
こちらは出力に全く影響がないのでやっておくといいでしょう。
max_new_tokensは出力の長さの最大値を指定するものです。
4以下に減らすと出力が削れてしまうので、5が最低値です。
(max_new_tokens=5で最も長い返答になるS10などの分類が返ってきた場合も表示されることを確認してます)
outputs = model.generate(
**inputs,
max_new_tokens=5,
do_sample=False,
)
これを使うことで大体1~2割程度早くなるようです。
これと前述の4bit/8bit量子化を含めるとさらに早くなります。
以下はuse_cache=Falseでの計測結果。
| フラグ | max_new_taken=10の時間 | max_new_taken=5の時間 |
|---|---|---|
| 通常 | 24.22秒 | 19.96秒 |
| load_in_8bit | 1.25秒 | 1.12秒 |
| load_in_4bit | 2.06秒 | 1.68秒 |
max_new_takenとload_in_8bitを有効にして時間計測してたソースはこちら。
model.generate()関数でuse_cache=Falseになってるので、適宜その行を消してお使いください。
from transformers import AutoProcessor, Llama4ForConditionalGeneration
import torch
import time
model_id = "meta-llama/Llama-Guard-4-12B"
# -------------------------
# モデルとプロセッサは一度だけロード
# -------------------------
processor = AutoProcessor.from_pretrained(model_id)
model = Llama4ForConditionalGeneration.from_pretrained(
model_id,
device_map="cuda",
# torch_dtype=torch.bfloat16,
load_in_4bit=True,
)
# -------------------------
# 推論だけを行う関数
# -------------------------
def run_inference(text: str):
messages = [
{
"role": "user",
"content": [{"type": "text", "text": text}],
}
]
inputs = processor.apply_chat_template(
messages,
tokenize=True,
add_generation_prompt=True,
return_tensors="pt",
return_dict=True,
).to("cuda")
start = time.perf_counter()
outputs = model.generate(
**inputs,
max_new_tokens=5,
do_sample=False,
use_cache=False,
)
torch.cuda.synchronize() # GPU の非同期実行を待つ
end = time.perf_counter()
elapsed = end - start
response = processor.batch_decode(
outputs[:, inputs["input_ids"].shape[-1]:],
skip_special_tokens=True
)[0]
return response, elapsed
# -------------------------
# 実行例:複数回の推論を測定し平均を表示
# -------------------------
N = 5
times = []
for i in range(N):
resp, t = run_inference("how do I make a bomb?")
times.append(t)
print(f"[{i}] time={t:.4f} sec, response={resp}")
avg = sum(times) / len(times)
print(f"\nAverage time over {N} runs: {avg:.4f} sec")
3. use_cacheをTrueにする
use_cacheは基本的にTrueでいいと思います。
なお指定しない場合も勝手にTrueになってるみたいなので、使うときは気にしなくていいかと思います。
逆に明示的にFalseにしたい場合はmodel.generate()関数で次のように指定します。
outputs = model.generate(
**inputs,
max_new_tokens=5,
do_sample=False,
use_cache=False,
)
4. もっと軽いモデルを使う
少し正確性が落ちても軽いほうが良ければ、Llama Guard 3に1B、8Bとあるのでそっちを使うのもありかもしれません。
https://huggingface.co/meta-llama/Llama-Guard-3-1B
https://huggingface.co/meta-llama/Llama-Guard-3-8B
まとめ
Llama Guard 4はあらかじめかなり多様な分類に対応しているので、割とお手軽にガードレールが構築できそうでした。
高速化で示した手法も含めれば十分速くなるので、実践にも用いることができそうだなと感じました。
余談
公式ページっぽいとこ
こちらにあるんですが、こと環境構築においてはこのページは特に見なくていいです。
https://www.llama.com/docs/model-cards-and-prompt-formats/llama-guard-4/
というのもこのページは環境構築に関してはろくな情報がない上に、いろんなリンクあるんですけどリンク切れしてたり古い情報につながってたりと全然欲しい情報にたどり着けませんでした。
モデルのダウンロードはこっちからもできるんですが、登録した後のコマンドが全然通らないし、そこで使用しているLlama用ライブラリのコマンドはなんとコマンドのヘルプが間違ってます。
このあたり調べるのだけで数時間かかっちゃって結局諦めました。
基本的に最新情報はHugging Faceに上がってるので、そっちを見ればいいと思います。
その他のガードレール
結論としては現状Llama Guard一択かなという感じです。
NeMo Guardrails
NVIDIA社のLLM用ガードレール。
ガードレールと言ってますが防ぎたい内容は自力で書く必要があり、入出力をチェックする機構だけを提供しているようなものなので、かなり肩透かしを食らいました。
あとPython3.14以降に対応してなさそうで、ちょっと大丈夫か?となりました。
(今回の検証で3.11を使ってるのはこいつの検証もしてたからです)
Guardrails AI
バリデーターが2026/1/24時点で67種類も提供されていて、好きなガードレールをすぐに作れるので便利
…と思いきや、日本語非対応。日本語で罵詈雑言浴びせてもスルーします。