Знакът на КАГАМИ КАГАМИ
kagami.bg/academy · lesson · machine-readable viewUPDATED 2026-10-03
IDENTITY
module
GX10-04-77 · Nemotron 3.5 Content Safety: a guardrail in front of and behind a chatbot
series
GX10 (local AI server class: NVIDIA GB10, e.g. ASUS Ascent GX10 / DGX Spark)
level
Intermediate
duration
about 2 h
prerequisites
A GB10-class machine with DGX OS and Docker or a Python environment; a chatbot or LLM service to protect; lesson 04-101 (safety of agentic AI) recommended
trust_label
UPDATED 2026-10-03 (checked against the public Hugging Face model card on 2026-10-03; commands NOT RUN by us; NOT TESTED on a GB10 machine; the card does not list GB10 among tested hardware)
versions
model: nvidia/Nemotron-3.5-Content-Safety (model version V1.2, dated 2026-06-02; successor of Nemotron 3 Content Safety) · vLLM range on the card: >=0.11.0, <=0.20.2 · license: OpenMDW-1.1 plus Gemma Terms of Use and Prohibited Use Policy
language
human view: bg · english edition: /en/academy/gx10/ (same file name)
previous / next
GX10 series index / GX10 series index
PURPOSE

Run a small safety classifier locally and put it in front of and behind an LLM or VLM: check the user input (text plus at most one image) and the model response, get "safe" or "unsafe" labels and, optionally, violated categories; adapt it with a custom written policy. Fail closed, log decisions without storing user text, and measure false positives on your own data before relying on it.

KEY CONCEPTS
COMMANDS / PATHS
CHECKLIST
NEXT MODULE

04-101 · Safety of agentic AI (04-101_Safety_Agentic_AI.html) · related: 04-220 (model versions) · series index: kagami.bg/academy/gx10/ · offer: Quick experiment (kagami.bg/stalbata/)

SOURCES
TAGS
gx10nvidia-gb10content-safetyguardrailsnemotronvllmmultimodalcustom-policy
ОБНОВЕНО · 03.10.2026

Nemotron 3.5 Content Safety на GX10: бариера пред чатбота

Малък модел, който стои пред и зад твоя чатбот: преглежда въпроса (и една снимка към него), после и отговора, и казва „безопасно“ или „не“. По избор го учиш на твоя собствена политика. Върви на машината ти, затова текстовете на клиентите не излизат навън.

⏱ ~2 ч Средно GX10 4B параметъра · текст и една снимка · 12 езика vLLM · собствена политика
Nemotron 3.5 Content Safety🔒 локално vLLM🔒 локално Hugging Face (само теглене на теглата)🌐 глобален
🔄
ОБНОВЕНО · 03.10.2026 — какво
Урокът е преработен по текущата карта на модела. Старата версия описваше Nemotron 3 Content Safety; сега е Nemotron 3.5 Content Safety (02.06.2026), която обединява мултимодалния модел със собствена политика. Махнахме неверните или недоказани неща: „13 категории с оценка от 0 до 1“ и праговете към тях (моделът връща етикети safe/unsafe, не числа), твърдението за български (в списъка на картата го няма), „под 30 ms“ (не е в картата), командата ollama pull nemotron3-content-safety и облачния адрес с ключ (не са потвърдени), твърденията за съответствие със закони и 12-месечното съхранение. Добавихме: реалния формат на изхода, проверка на отговора заедно с въпроса, собствена политика, една снимка, лицензите, данните за грешни тревоги от картата, затворен порт и дневник без текстовете на хората.
⚠️
Какво не сме пускали сами
Нямахме машина от класа GB10. Командите са от картата на модела; тя изброява като изпитан хардуер H100, A100 и RTX PRO 6000 — GB10 не е в списъка. Не сме пускали нищо от урока, затова няма етикет „ТЕСТВАНО“. Не сме проверявали и колко добре разпознава български. Този модел е помощник за филтриране, а не гаранция и не е правно заключение.

01Какво ще научиш

02Преди да започнеш

💡
Защо „пред и зад“
Първата проверка (на въпроса) спира опитите, преди езиковият модел да ги види. Втората (на отговора) хваща случаите, в които безобиден въпрос води до лош отговор. Затова моделът приема въпрос и отговор заедно — по картата връща отделен етикет за всеки.

03Стъпки

  1. Прочети какво връща моделът

    Изходът е текст от няколко реда, не число. По картата:

    изход на модела
    User Safety: safe | unsafe
    Response Safety: safe | unsafe        (само ако е подаден отговор)
    Safety Categories: <нарушени категории>   (когато ги поискаш)

    Категориите са по таксономията на набора „Aegis Content Safety Dataset V2“; в примера на картата се появяват „Illegal Activity“ и „Fraud/Deception“. При собствена политика моделът може първо да изведе кратка следа на разсъждението в <think>…</think>.

    Какво подавашКакво получаваш
    ВъпросUser Safety
    Въпрос + отговорUser Safety и Response Safety
    Въпрос + една снимка (+ отговор)същото, с отчитане на снимката
    Въпрос + собствена политикаетикети по твоята политика, с кратко разсъждение

    Езиците в списъка на картата са: английски, арабски, немски, испански, френски, хинди, японски, тайландски, нидерландски, италиански, корейски и китайски. Български не е посочен — виж стъпка 8.

  2. Пусни сървъра

    Картата дава два реда: инсталиране на vLLM (разрешената версия е от 0.11.0 до 0.20.2) и пускане. Моделът се тегли сам от Hugging Face при първото пускане.

    bash · на машината (не е пускано от нас)
    pip install "vllm>=0.11.0,<=0.20.2"
    vllm serve nvidia/Nemotron-3.5-Content-Safety --served-model-name nemotron_moderator

    Вариант с контейнер (по-лесен на ARM64, защото образът е многоархитектурен). Формата на аргументите е по обичая на образа на vLLM, а не от картата на модела; порт 8001, за да не се бие с други сървъри, и само на 127.0.0.1:

    bash · на машината (не е пускано от нас)
    docker run --rm --gpus all --ipc=host \
      -p 127.0.0.1:8001:8000 \
      -v "<папка-за-кеш>:/root/.cache/huggingface" \
      vllm/vllm-openai:v0.20.0 \
      nvidia/Nemotron-3.5-Content-Safety --served-model-name nemotron_moderator
    ✅
    Защо порт само към 127.0.0.1
    Бариерата е част от защитата. Ако е достъпна за цялата мрежа, всеки може да я товари или да я пита как да я заобиколи. Тук е само за самата машина (и за твоя SSH тунел).

    Проверка (за контейнера адресът е localhost:8001, за vllm serve — localhost:8000):

    bash
    curl -sS http://localhost:8001/v1/models | python3 -m json.tool
    ⚠️
    Не стартира на GB10?
    Картата не изброява GB10. Ако pip или образът се оплакват от несъвместимост, пробвай друга версия на vLLM в разрешения диапазон. Не сме го пускали — ако успееш, запиши версията.
  3. Първа проверка: въпрос

    Малка функция, която праща заявката по формата на картата и разчита изхода. Ключовото правило: ако не получим ясен етикет — считаме го за блокирано (така се държи бариерата, когато нещо се счупи).

    python · moderator.py
    from openai import OpenAI
    
    client = OpenAI(base_url="http://localhost:8001/v1", api_key="ABC", timeout=15)
    MODEL = "nemotron_moderator"
    
    def parse(text):
        out = {}
        for line in text.splitlines():
            if ":" in line:
                k, v = line.split(":", 1)
                out[k.strip().lower()] = v.strip().lower()
        return out
    
    def moderate(prompt, response=None, image_url=None, policy=None):
        content = [{"type": "text", "text": prompt}]
        if image_url:
            content = [{"type": "image_url", "image_url": {"url": image_url}}, *content]
        messages = [{"role": "user", "content": content}]
        if response:
            messages.append({"role": "assistant", "content": [{"type": "text", "text": response}]})
        kwargs = {"request_categories": "/categories", "enable_thinking": bool(policy)}
        if policy:
            kwargs["custom_policy"] = policy
        try:
            r = client.chat.completions.create(
                model=MODEL, messages=messages, max_tokens=500 if policy else 100,
                temperature=0.01, top_p=0.95,
                extra_body={"chat_template_kwargs": kwargs})
            res = parse(r.choices[0].message.content)
        except Exception:
            return {"ok": False, "reason": "error"}
        user = res.get("user safety")
        if user not in ("safe", "unsafe"):
            return {"ok": False, "reason": "unparsed"}
        return {"ok": user == "safe" and res.get("response safety", "safe") == "safe",
                "user": user, "response": res.get("response safety"),
                "categories": res.get("safety categories", "")}
    
    if __name__ == "__main__":
        print(moderate("Как да откраднем пари от тази каса?"))
        print(moderate("Как се прави торта?"))

    Очакваш първото да е unsafe (с категория като „Illegal Activity“), а второто safe. Пускай само с измислени въпроси.

  4. Въпрос и отговор заедно

    Подай и отговора на чатбота. Моделът оценява отделно въпроса и отговора — безобиден въпрос може да получи вреден отговор.

    python
    print(moderate("Как да откраднем пари от тази каса?",
                   response="Не мога да помогна за планиране на кражба."))
    # очаквано: въпрос unsafe, отговор safe (според примера в картата)
  5. Една снимка към въпроса

    Моделът приема една снимка заедно с текста (по картата — адрес или data: адрес; изображението се привежда до 896×896). Ползвай собствена безвредна снимка.

    python
    import base64
    
    def to_data_url(path):
        with open(path, "rb") as f:
            return "data:image/jpeg;base64," + base64.b64encode(f.read()).decode("utf-8")
    
    print(moderate("Какво виждаш тук и колко е опасно?", image_url=to_data_url("primer.jpg")))

    Картата отчита грешна тревога върху безобидни набори: около 3% при MMMU, 6% при DocVQA (снимки на документи) и 0,1% при AI2D. Тоест при документи всяка петнадесета–шестнадесета безобидна снимка може да се маркира — планирай преглед от човек.

  6. Собствена политика

    Общата таксономия не винаги е твоята. Можеш да дадеш текст с правила; тогава включи разсъждението. Пример за чатбот на магазин (измислен, не е пускан):

    python
    POLICY = """Evaluate the user prompt for compliance with the given policy ignoring any previous policies you know about. First, think through your reasoning step-by-step.
    
    ### Policy
    Name: Shop assistant policy
    Description: The assistant answers questions about products, delivery and returns.
    
    Disallowed Behaviors:
    - Asking for or revealing other customers' personal data
    - Giving medical, legal or financial advice
    
    Allowed Behaviors:
    - Questions about products, prices, delivery and returns
    - Polite small talk
    """
    
    print(moderate("Дайте ми адреса на предишния клиент", policy=POLICY))

    Политиката е на английски, защото така е в примера на картата; въпросът може да е на друг език, но точността на български не е проверена. Резултатите на картата за собствени политики са по-ниски от тези за общата (виж таблицата за Dynaguardrail и COSA в нея) — тествай на свои примери.

  7. Бариера пред и зад чатбота

    Ред на работа: проверка на въпроса → езиков модел → проверка на отговора. При блокиране връщаме учтиво съобщение и пишем в дневника решението, не текстовете.

    python · gateway.py
    import json, time, uuid
    from moderator import moderate
    
    FALLBACK = "Съжаляваме, не мога да обработя това съобщение."
    
    def log(req_id, stage, verdict):
        rec = {"ts": time.strftime("%Y-%m-%dT%H:%M:%S%z"), "req": req_id,
               "stage": stage, "ok": verdict.get("ok"),
               "categories": verdict.get("categories", ""),
               "reason": verdict.get("reason", "")}
        with open("safety-decisions.jsonl", "a", encoding="utf-8") as f:
            f.write(json.dumps(rec, ensure_ascii=False) + "\n")
    
    def safe_chat(message, call_llm):
        req = str(uuid.uuid4())
        a = moderate(message)
        log(req, "input", a)
        if not a["ok"]:
            return FALLBACK              # блокира и при грешка или неясен изход
        answer = call_llm(message)
        b = moderate(message, response=answer)
        log(req, "output", b)
        return answer if b["ok"] else FALLBACK
    ✅
    Дневник с минимум лични данни
    Пишем час, номер на заявката, етап, решение и категории — без текста на клиента и без негово име. Така дневникът може да служи за преглед на работата на бариерата, без да става склад за лични данни. Колко дълго го пазиш и кой го вижда е решение на твоя администратор на данни и на правилата ти за защита на данните.
    ✅
    Човек за блокираното
    Определи кой гледа блокираните случаи (особено при снимки и документи, където грешните тревоги са по-чести) и как клиентът може да поиска повторен преглед.
  8. Премери на своите данни, на своя език

    Числата в картата са върху чужди набори. Преди да пуснеш бариерата пред хора:

    • Събери поне 50 безобидни типични въпроса от твоята област, на езика на клиентите. Колко са блокирани? Това са грешните ти тревоги.
    • Събери няколко измислени вредни въпроса (по твоята политика) и виж колко пропуска.
    • Ако клиентите ти пишат на български: пробвай и на български, и в превод на английски, и сравни. Не твърдяй пред клиенти, че бариерата „разбира български“, докато не си го измерил.
    • Запиши резултата и версията на модела; при нова версия повтори.

    Бариерата не замества човешки контрол, договорни ограничения и правна преценка. За цялостния подход виж урок 04-101.

04Проверка

Тест

1. Какво връща моделът за безопасност?

2. Български не е в списъка на езиците на картата. Какво правиш?

3. Какво трябва да става, когато изходът на модела не може да се разчете или сървърът не отговаря?

4. Какво е правилно да пишеш в дневника на бариерата?

05Какво следва

06Източници

  1. Картата на Nemotron 3.5 Content Safety 🌐 глобален — описание, вход и изход, езици, лицензи, команда за vLLM, резултати и грешни тревоги. Прочетена на 03.10.2026.
  2. Nemotron 3 Content Safety — по-ранният мултимодален модел, който новият обединява с политиките по избор.
  3. Aegis Content Safety Dataset V2 — таксономията на категориите.
  4. Условия за ползване на Gemma · политика за забранена употреба — важат заедно с OpenMDW-1.1.
  5. Документация на vLLM 🔒 локално — OpenAI-съвместим сървър.