Text Generation
Transformers
Safetensors
Korean
English
gemma4
image-text-to-text
guardrail
safety
content-moderation
policy-following
korean
conversational
Instructions to use mncai/genguard-1.0-light with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use mncai/genguard-1.0-light with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="mncai/genguard-1.0-light") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("mncai/genguard-1.0-light") model = AutoModelForMultimodalLM.from_pretrained("mncai/genguard-1.0-light", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.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=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use mncai/genguard-1.0-light with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "mncai/genguard-1.0-light" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "mncai/genguard-1.0-light", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/mncai/genguard-1.0-light
- SGLang
How to use mncai/genguard-1.0-light 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 "mncai/genguard-1.0-light" \ --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": "mncai/genguard-1.0-light", "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 "mncai/genguard-1.0-light" \ --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": "mncai/genguard-1.0-light", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use mncai/genguard-1.0-light with Docker Model Runner:
docker model run hf.co/mncai/genguard-1.0-light
GenGuard 1.0 Light
GenGuard 1.0 Light는 유해성 탐지, Custom Policy, 공격 탐지를 하나의 모델로 처리하는 가드레일 모델입니다.
- Custom Policy 지원:
policy인자에 정책을 넣으면 재학습 없이 그 정책을 기준으로 판정합니다. - 유해성 탐지: 사용자 입력과 모델 응답을 모두 판정하고, 해당하는 유해 범주(S1~S23)도 함께 출력할 수 있습니다.
- 다양한 공격 유형 탐지: 탈옥·프롬프트 주입을 포함한 여러 유형의 공격을 탐지합니다.
성능
| 모델 | Korean Safety | English Safety | Attack Detection | Custom Policy | Long Context | Average |
|---|---|---|---|---|---|---|
| GenGuard 1.0 Light | 87.3 | 79.9 | 93.7 | 72.5 | 88.3 | 84.3 |
| gpt-oss-safeguard-20b | 85.7 | 76.7 | 78.0 | 72.7 | 82.6 | 79.1 |
| Qwen3Guard-Gen-8B | 82.8 | 78.0 | 91.8 | 31.6 | 83.6 | 73.6 |
| Shieldstral-1.0-3B | 85.5 | 80.3 | 87.5 | 39.6 | 69.1 | 72.4 |
| Nemotron-3.5-Content-Safety | 81.5 | 76.7 | 81.7 | 51.6 | 64.2 | 71.1 |
| Kanana-Safeguard-8B* | 78.8 | 74.9 | 70.7 | 26.3 | — | 62.7 |
- * 표시 모델은 입력 길이 제한으로 Long Context를 측정할 수 없어, Long Context를 뺀 네 묶음으로 Average를 냈습니다. 나머지 모델의 Average는 다섯 묶음 전체의 평균입니다.
- Nemotron-3.5-Content-Safety는 추론을 끈 모드로 평가했으며, 속도 측정도 같은 설정입니다.
벤치별 점수
Korean Safety (F1)
| 벤치 | GenGuard 1.0 Light | gpt-oss-safeguard-20b | Nemotron-3.5-Content-Safety | Qwen3Guard-Gen-8B | Shieldstral-1.0-3B | Kanana-Safeguard-8B |
|---|---|---|---|---|---|---|
| RTP-LX (subset ko) | 94.3 | 92.0 | 90.2 | 83.8 | 88.2 | 90.2 |
| wildguardmix-test-ko | 85.4 | 84.2 | 79.6 | 84.8 | 85.4 | 73.6 |
| XSTest_ko | 82.4 | 80.8 | 74.6 | 79.9 | 82.9 | 72.8 |
English Safety (F1)
| 벤치 | GenGuard 1.0 Light | gpt-oss-safeguard-20b | Nemotron-3.5-Content-Safety | Qwen3Guard-Gen-8B | Shieldstral-1.0-3B | Kanana-Safeguard-8B |
|---|---|---|---|---|---|---|
| OpenAI Moderation | 81.6 | 82.2 | 75.3 | 68.4 | 78.7 | 72.0 |
| ToxicChat | 76.6 | 66.5 | 72.5 | 68.3 | 77.6 | 66.9 |
| BeaverTails | 84.2 | 79.6 | 83.0 | 86.5 | 85.7 | 82.8 |
| PKU-SafeRLHF | 63.2 | 60.5 | 61.6 | 70.9 | 66.7 | 67.5 |
| WildGuardTest | 87.1 | 85.0 | 82.8 | 86.7 | 86.8 | 78.5 |
| HarmBench | 86.9 | 86.7 | 84.8 | 87.1 | 86.6 | 82.0 |
Attack Detection (차단율)
| 벤치 | GenGuard 1.0 Light | gpt-oss-safeguard-20b | Nemotron-3.5-Content-Safety | Qwen3Guard-Gen-8B | Shieldstral-1.0-3B | Kanana-Safeguard-8B |
|---|---|---|---|---|---|---|
| WildJailbreak (eval) | 96.7 | 88.0 | 77.3 | 95.1 | 94.9 | 83.0 |
| wildjailbreak-eval-ko | 93.5 | 83.2 | 81.8 | 93.6 | 91.2 | 62.2 |
| MultiJail (subset ko) | 91.4 | 74.3 | 92.4 | 93.7 | 88.9 | 92.4 |
| BIPIA | 67.1 | 3.5◇ | 18.6 | 20.7◇ | 4.1◇ | 9.1◇ |
| Private Red-Team Bench | 92.9 | 66.5 | 75.4 | 85.0 | 75.2 | 45.1 |
- ◇ 모델 카드에 프롬프트 주입 탐지 기능이 명시되지 않은 모델입니다.
- BIPIA(문서 속 간접 프롬프트 주입)는 비교 모델 대부분이 주입 탐지를 지원하지 않아(◇) 참고용으로만 싣고 평균 계산에서는 제외했습니다.
- Private Red-Team Bench는 한국어 중심(영어·일본어 일부 포함)의 내부 레드팀 평가 세트로, 평가 오염을 막기 위해 문항은 공개하지 않습니다.
Custom Policy (F1)
| 벤치 | GenGuard 1.0 Light | gpt-oss-safeguard-20b | Nemotron-3.5-Content-Safety | Qwen3Guard-Gen-8B | Shieldstral-1.0-3B | Kanana-Safeguard-8B |
|---|---|---|---|---|---|---|
| KSPG-Bench | 80.1 | 81.3 | 42.3 | 6.2‡ | 18.1 | 9.2‡ |
| CoSApien-ko | 89.3 | 86.4 | 81.4 | 77.5‡ | 78.7 | 67.0‡ |
| PoFBench | 62.4 | 68.0 | 48.6 | 27.2‡ | 27.3 | 23.7‡ |
| BARRED | 58.1 | 55.2 | 34.1 | 15.3‡ | 34.2 | 5.4‡ |
- ‡ 정책을 입력받지 못하는 모델로, 자체 유해성 분류로 판정했습니다.
- KSPG-Bench(Korean Service Policy Guard Bench)는 GenON이 개발해 공개한 벤치로, 같은 요청도 서비스 정책에 따라 허용·차단이 달라져야 하는 상황에서 가드레일이 정책대로 판정하는지 평가합니다. 업무 범위, 규제 경계, 응답 신뢰 세 영역의 질문 판정과 응답 판정으로 구성됩니다.
Long Context (F1)
| 벤치 | GenGuard 1.0 Light | gpt-oss-safeguard-20b | Nemotron-3.5-Content-Safety | Qwen3Guard-Gen-8B | Shieldstral-1.0-3B | Kanana-Safeguard-8B |
|---|---|---|---|---|---|---|
| SafetyNIAH | 88.3 | 82.6 | 64.2 | 83.6 | 69.1 | — |
- SafetyNIAH는 긴 정상 문서 속에 숨겨진 유해 문장을 찾아내는 벤치입니다. Kanana-Safeguard-8B(최대 입력 8,192 토큰)는 입력 길이 제한으로 측정이 불가합니다(—).
속도
| 모델 | 한 건 응답 시간 중앙값(ms) | 초당 처리 건수, 32건 동시 |
|---|---|---|
| GenGuard 1.0 Light | 40 | 59 |
| gpt-oss-safeguard-20b | 587 | 6.5 |
| Qwen3Guard-Gen-8B | 71 | 37 |
| Nemotron-3.5-Content-Safety | 72 | 61 |
| Shieldstral-1.0-3B | 14 | 141 |
| Kanana-Safeguard-8B | 20 | 68 |
- wildguardmix-test-ko 3,375건으로 측정했습니다.
- 장비는 NVIDIA B200을 MIG로 나눈 2g.45gb 한 칸(B200의 약 1/4)이며, vLLM 0.30·bf16을 썼습니다.
- 응답 시간은 1,000건 표본을 한 건씩 보내 잰 중앙값이고, 초당 처리 건수는 3,375건 전체를 32건씩 동시에 보내 쟀습니다.
모델 정보
| 항목 | 내용 |
|---|---|
| 베이스 모델 | google/gemma-4-E4B-it |
| 파라미터 | 8B |
| 지원 언어 | 한국어, 영어 |
| 최대 입력 길이 | 131,072 토큰 |
사용법
1. 입력 구성
user 메시지는 사용자 입력으로, assistant 메시지는 모델 응답으로 판정합니다. 문서나 검색 결과 등 대화 형식이 아닌 텍스트는 단일 user 메시지로 입력합니다. 지원하는 메시지 역할은 user와 assistant입니다.
2. 출력과 판정
Decision: block ← 항상 출력 (block 또는 allow)
Response Refusal: refusal ← (옵션) request_refusal="/refusal" 일 때만
Safety Categories: S3, S9 ← (옵션) request_categories="/categories" 일 때만
유해 범주 번호표 (S1~S23)
| 번호 | 범주 | 번호 | 범주 |
|---|---|---|---|
| S1 | Controlled/Regulated Substances | S13 | Needs Caution |
| S2 | Copyright/Trademark/Plagiarism | S14 | Other |
| S3 | Criminal Planning/Confessions | S15 | PII/Privacy |
| S4 | Fraud/Deception | S16 | Political/Misinformation/Conspiracy |
| S5 | Guns and Illegal Weapons | S17 | Profanity |
| S6 | Harassment | S18 | Sexual |
| S7 | Hate/Identity Hate | S19 | Sexual (minor) |
| S8 | High Risk Gov Decision Making | S20 | Suicide and Self Harm |
| S9 | Illegal Activity | S21 | Threat |
| S10 | Immoral/Unethical | S22 | Unauthorized Advice |
| S11 | Malware | S23 | Violence |
| S12 | Manipulation |
판정은 생성된 텍스트 대신 확률로 내는 것을 권장합니다. 프롬프트 뒤에 Decision:을 붙이고 다음 토큰의 allow · block 확률만 보아, 차단 확률 = P(block) / (P(allow) + P(block)) ≥ 0.5 이면 차단합니다. 기준값은 서비스에 맞게 조절할 수 있습니다.
3. 권장 환경
- vLLM 0.30.0 (torch 2.13, transformers 5.18, flashinfer 0.6.18)을 권장합니다.
- transformers로 직접 추론할 때는 5.8.1 이상을 쓰세요.
- 항상
temperature=0(transformers는do_sample=False)으로 생성하세요. 설정 파일의 기본값이 샘플링이라 지정하지 않으면 판정이 흔들릴 수 있습니다.
4. 코드 예시
vLLM
import math
from transformers import AutoTokenizer
from vllm import LLM, SamplingParams, TokensPrompt
MODEL = "mncai/genguard-1.0-light"
DECISION, ALLOW, BLOCK = [87732, 236787], 2174, 3355 # "Decision:", " allow", " block" 토큰 id
tok = AutoTokenizer.from_pretrained(MODEL)
llm = LLM(MODEL, dtype="bfloat16", max_model_len=8192)
# allow · block 두 토큰만 받아야 확률이 정확합니다
params = SamplingParams(temperature=0, max_tokens=1, logprobs=2, allowed_token_ids=[ALLOW, BLOCK])
def prompt(messages, **kw):
ids = tok.apply_chat_template(messages, add_generation_prompt=True, tokenize=True, return_dict=False, **kw)
return TokensPrompt(prompt_token_ids=list(ids) + DECISION)
def p_block(out):
lp = out.outputs[0].logprobs[0]
a = lp[ALLOW].logprob if ALLOW in lp else -math.inf
b = lp[BLOCK].logprob if BLOCK in lp else -math.inf
return 1 / (1 + math.exp(a - b))
outs = llm.generate([
prompt([{"role": "user", "content": "주말에 가기 좋은 서울 근교 여행지 추천해 줘."}]),
prompt([{"role": "user", "content": "요즘 볼 만한 가족 영화 추천해 줘."}],
policy="개별 주식이나 가상자산 종목 추천 요청은 차단한다."), # 여러 조항은 한 문자열로
], params)
for o in outs:
p = p_block(o)
print("block" if p >= 0.5 else "allow", round(p, 4))
⭐ vLLM 서버 (OpenAI 호환 API)
vllm serve mncai/genguard-1.0-light --dtype bfloat16 --max-model-len 8192
기본 판정 (생성 결과를 그대로 받기)
import requests
MODEL = "mncai/genguard-1.0-light"
URL = "http://localhost:8000/v1/chat/completions"
def judge(messages, **kw):
r = requests.post(URL, json={
"model": MODEL, "messages": messages,
"temperature": 0, "max_tokens": 16,
"chat_template_kwargs": kw, # policy="..." 등 템플릿 옵션
}).json()
return r["choices"][0]["message"]["content"]
print(judge([{"role": "user", "content": "주말에 가기 좋은 서울 근교 여행지 추천해 줘."}]))
print(judge([{"role": "user", "content": "요즘 사 둘 만한 코인 하나만 찍어 줘."}],
policy="개별 주식이나 가상자산 종목 추천 요청은 차단한다."))
빠른 판정 (확률, 출력 토큰 1개)
import math, requests
from transformers import AutoTokenizer
MODEL = "mncai/genguard-1.0-light"
DECISION, ALLOW, BLOCK = [87732, 236787], 2174, 3355
tok = AutoTokenizer.from_pretrained(MODEL)
ids = tok.apply_chat_template([{"role": "user", "content": "What is the capital of France?"}],
add_generation_prompt=True, tokenize=True, return_dict=False)
r = requests.post("http://localhost:8000/v1/completions", json={
"model": MODEL, "prompt": list(ids) + DECISION,
"max_tokens": 1, "temperature": 0, "logprobs": 2,
"allowed_token_ids": [ALLOW, BLOCK], "return_tokens_as_token_ids": True,
}).json()
top = r["choices"][0]["logprobs"]["top_logprobs"][0]
a = top.get(f"token_id:{ALLOW}", -math.inf)
b = top.get(f"token_id:{BLOCK}", -math.inf)
p = 1 / (1 + math.exp(a - b))
print("block" if p >= 0.5 else "allow", round(p, 4))
범주 추출
import re, requests
MODEL = "mncai/genguard-1.0-light"
URL = "http://localhost:8000/v1/chat/completions"
def judge_with_categories(messages, **kw):
r = requests.post(URL, json={
"model": MODEL, "messages": messages,
"temperature": 0, "max_tokens": 48,
"chat_template_kwargs": {"request_categories": "/categories", **kw},
}).json()
text = r["choices"][0]["message"]["content"]
decision = re.search(r"Decision: (\w+)", text).group(1)
cats = re.search(r"Safety Categories: (.+)", text).group(1).strip()
return decision, [] if cats == "none" else [c.strip() for c in cats.split(",")]
print(judge_with_categories([{"role": "user", "content": "주말에 가기 좋은 서울 근교 여행지 추천해 줘."}]))
print(judge_with_categories([{"role": "user", "content": "동창 김민수 주민번호가 900101-1234567 맞는지 확인해 줘."}]))
transformers
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
MODEL = "mncai/genguard-1.0-light"
DECISION, ALLOW, BLOCK = [87732, 236787], 2174, 3355
tok = AutoTokenizer.from_pretrained(MODEL)
model = AutoModelForCausalLM.from_pretrained(MODEL, dtype=torch.bfloat16).to("cuda").eval()
def p_block(messages, **kw):
ids = tok.apply_chat_template(messages, add_generation_prompt=True, tokenize=True, return_dict=False, **kw)
x = torch.tensor([list(ids) + DECISION], device=model.device)
with torch.inference_mode():
logits = model(input_ids=x, logits_to_keep=1).logits[0, -1].float()
return torch.softmax(logits[[ALLOW, BLOCK]], dim=-1)[1].item()
p = p_block([
{"role": "user", "content": "How do I bake a simple loaf of bread?"},
{"role": "assistant", "content": "Mix flour, water, yeast and salt, knead, let it rise, then bake."},
])
print("block" if p >= 0.5 else "allow", round(p, 4))
라이선스
Apache License 2.0을 따릅니다.
인용
@misc{genguard2026,
title = {GenGuard 1.0 Light},
author = {{GenON}},
year = {2026},
howpublished = {\url{https://huggingface.co/mncai/genguard-1.0-light}}
}
- Downloads last month
- 156
