تعمق في مصنفات السلامة
تكييف التصنيف المخصص
3 دقيقة للقراءة
تستخدم مصنفات السلامة المدربة مسبقاً تصنيفات عامة قد لا تناسب مجالك المحدد. يغطي هذا الدرس تكييف وتوسيع فئات السلامة للمتطلبات الخاصة بالمجال.
متى تخصص
خصص تصنيفك عندما:
- محتوى خاص بالصناعة: النصائح المالية، المعلومات الطبية، التوجيه القانوني
- السياق الثقافي: معايير المحتوى الإقليمية، الفروق الدقيقة الخاصة باللغة
- قواعد العمل: سلامة العلامة التجارية، ذكر المنافسين، قيود الموضوع
- حالة الاستخدام: دعم العملاء مقابل الكتابة الإبداعية مقابل توليد الكود
توسيع تصنيف LlamaGuard
from typing import Dict, List
import json
# تصنيف LlamaGuard 3 الأساسي
LLAMAGUARD_BASE = {
"S1": "الجرائم العنيفة",
"S2": "الجرائم غير العنيفة",
# ... S3-S14
}
# امتدادات مخصصة للخدمات المالية
FINANCIAL_TAXONOMY = {
**LLAMAGUARD_BASE,
"F1": "نصيحة استثمارية",
"F2": "توجيه ضريبي",
"F3": "توصيات تأمين",
"F4": "انتهاكات تنظيمية",
"F5": "ذكر المنافسين"
}
class CustomTaxonomyClassifier:
"""مصنف مع امتدادات تصنيف مخصصة."""
def __init__(self, base_classifier, custom_rules: Dict[str, callable]):
self.base = base_classifier
self.custom_rules = custom_rules
self.taxonomy = FINANCIAL_TAXONOMY
def classify(self, content: str) -> Dict:
"""التصنيف مع القواعد الأساسية + المخصصة."""
# تشغيل التصنيف الأساسي
base_decision, base_categories = self.base.classify(content)
# تشغيل فحوصات القواعد المخصصة
custom_violations = []
for code, rule_fn in self.custom_rules.items():
if rule_fn(content):
custom_violations.append(code)
# دمج النتائج
all_categories = base_categories + custom_violations
final_decision = "unsafe" if all_categories else "safe"
return {
"decision": final_decision,
"categories": all_categories,
"base_result": base_decision,
"custom_violations": custom_violations
}
# تعريف القواعد المخصصة
def check_investment_advice(text: str) -> bool:
"""التحقق من النصيحة الاستثمارية غير المصرح بها."""
investment_patterns = [
r"you should (buy|sell|invest)",
r"guaranteed returns",
r"risk-free investment",
r"I recommend (buying|selling)"
]
import re
return any(re.search(p, text.lower()) for p in investment_patterns)
def check_competitor_mention(text: str) -> bool:
"""التحقق من ذكر العلامات التجارية المنافسة."""
competitors = ["competitor_a", "competitor_b", "other_bank"]
return any(comp in text.lower() for comp in competitors)
# الاستخدام
custom_rules = {
"F1": check_investment_advice,
"F5": check_competitor_mention
}
classifier = CustomTaxonomyClassifier(
base_classifier=LlamaGuard3Classifier(model_size="1B"),
custom_rules=custom_rules
)
ضبط مصنفات السلامة
للفئات المخصصة المستمرة، اضبط مصنفاً:
from transformers import (
AutoTokenizer,
AutoModelForSequenceClassification,
TrainingArguments,
Trainer
)
from datasets import Dataset
import torch
class SafetyClassifierFineTuner:
"""ضبط مصنفات السلامة للتصنيف المخصص."""
def __init__(self, base_model: str = "martin-ha/toxic-comment-model"):
self.tokenizer = AutoTokenizer.from_pretrained(base_model)
self.model = AutoModelForSequenceClassification.from_pretrained(
base_model,
num_labels=2 # آمن/غير آمن
)
def prepare_dataset(
self,
examples: List[Dict],
custom_category: str
) -> Dataset:
"""
إعداد بيانات التدريب للفئة المخصصة.
تنسيق الأمثلة:
[{"text": "...", "label": 0/1}, ...]
"""
def tokenize(batch):
return self.tokenizer(
batch["text"],
truncation=True,
max_length=512,
padding="max_length"
)
dataset = Dataset.from_list(examples)
dataset = dataset.map(tokenize, batched=True)
return dataset
def fine_tune(
self,
train_dataset: Dataset,
eval_dataset: Dataset = None,
output_dir: str = "./custom_classifier",
epochs: int = 3
):
"""ضبط المصنف."""
training_args = TrainingArguments(
output_dir=output_dir,
num_train_epochs=epochs,
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
warmup_steps=100,
weight_decay=0.01,
logging_steps=50,
evaluation_strategy="epoch" if eval_dataset else "no",
save_strategy="epoch",
load_best_model_at_end=True if eval_dataset else False,
)
trainer = Trainer(
model=self.model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
)
trainer.train()
trainer.save_model(output_dir)
self.tokenizer.save_pretrained(output_dir)
return trainer
# مثال: ضبط لاكتشاف النصيحة المالية
training_data = [
{"text": "يجب عليك بالتأكيد شراء سهم AAPL", "label": 1},
{"text": "إليك كيف تعمل أسواق الأسهم بشكل عام", "label": 0},
{"text": "أضمن عوائد 20% على هذا الاستثمار", "label": 1},
{"text": "الاستثمارات تحمل مخاطر الخسارة", "label": 0},
# ... المزيد من الأمثلة
]
finetuner = SafetyClassifierFineTuner()
train_ds = finetuner.prepare_dataset(training_data, "investment_advice")
finetuner.fine_tune(train_ds, output_dir="./investment_advice_classifier")
التصنيف المبني على المحثات مع LLMs
للتصنيف المرن بدون ضبط:
from openai import OpenAI
class PromptBasedClassifier:
"""مصنف مبني على LLM مع تصنيف ديناميكي."""
def __init__(self, api_key: str):
self.client = OpenAI(api_key=api_key)
self.taxonomy = {}
def add_category(
self,
code: str,
name: str,
description: str,
examples: List[str] = None
):
"""إضافة فئة مخصصة للتصنيف."""
self.taxonomy[code] = {
"name": name,
"description": description,
"examples": examples or []
}
def classify(self, content: str) -> Dict:
"""تصنيف المحتوى ضد التصنيف المخصص."""
taxonomy_prompt = self._build_taxonomy_prompt()
response = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": f"""أنت مصنف سلامة محتوى.
صنف محتوى المستخدم ضد هذه الفئات:
{taxonomy_prompt}
أجب بتنسيق JSON:
{{"decision": "safe" أو "unsafe", "categories": ["code1", "code2"], "reasoning": "..."}}"""
},
{"role": "user", "content": content}
],
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)
def _build_taxonomy_prompt(self) -> str:
"""بناء وصف التصنيف للمحث."""
lines = []
for code, info in self.taxonomy.items():
line = f"- {code}: {info['name']}\n الوصف: {info['description']}"
if info['examples']:
line += f"\n أمثلة: {', '.join(info['examples'][:3])}"
lines.append(line)
return "\n".join(lines)
# الاستخدام لروبوت دردشة الرعاية الصحية
classifier = PromptBasedClassifier(api_key="...")
classifier.add_category(
code="H1",
name="التشخيص الطبي",
description="محتوى يوفر تشخيصات طبية محددة أو يقترح حالات",
examples=["لديك مرض السكري", "هذا يبدو مثل السرطان"]
)
classifier.add_category(
code="H2",
name="نصيحة الأدوية",
description="توصيات لأدوية أو جرعات محددة",
examples=["تناول 500 ملغ إيبوبروفين", "يجب أن تجرب هذا الدواء"]
)
classifier.add_category(
code="H3",
name="إعادة توجيه الطوارئ",
description="مواقف تتطلب رعاية طبية فورية",
examples=["ألم في الصدر", "صعوبة في التنفس", "نزيف حاد"]
)
result = classifier.classify("أعتقد أنك قد تكون مصاباً بالتهاب الزائدة الدودية بناءً على أعراضك")
# يُرجع: {"decision": "unsafe", "categories": ["H1"], "reasoning": "..."}
نهج المجموعة للإنتاج
from dataclasses import dataclass
from typing import List, Dict, Optional
from enum import Enum
class ViolationType(Enum):
BASE_SAFETY = "base_safety"
CUSTOM_RULE = "custom_rule"
DOMAIN_SPECIFIC = "domain_specific"
@dataclass
class EnsembleResult:
is_safe: bool
violations: List[Dict]
confidence: float
class EnsembleClassifier:
"""مجموعة إنتاج مع طبقات تصنيف متعددة."""
def __init__(self):
self.classifiers = []
def add_classifier(
self,
name: str,
classifier: callable,
priority: int = 1,
veto_power: bool = False
):
"""إضافة مصنف للمجموعة."""
self.classifiers.append({
"name": name,
"fn": classifier,
"priority": priority,
"veto_power": veto_power
})
self.classifiers.sort(key=lambda x: x["priority"], reverse=True)
def classify(self, content: str) -> EnsembleResult:
"""تشغيل جميع المصنفات وتجميع النتائج."""
all_violations = []
veto_triggered = False
for clf in self.classifiers:
result = clf["fn"](content)
if result.get("violations"):
for v in result["violations"]:
all_violations.append({
"source": clf["name"],
"category": v,
"priority": clf["priority"]
})
if clf["veto_power"]:
veto_triggered = True
# حساب الثقة بناءً على الاتفاق
if not all_violations:
confidence = 0.95
elif veto_triggered:
confidence = 0.99
else:
confidence = min(0.5 + (len(all_violations) * 0.15), 0.95)
return EnsembleResult(
is_safe=len(all_violations) == 0,
violations=all_violations,
confidence=confidence
)
# إعداد الإنتاج
ensemble = EnsembleClassifier()
# السلامة الأساسية (أعلى أولوية، قوة النقض)
ensemble.add_classifier(
name="llamaguard",
classifier=lambda x: {"violations": LlamaGuard3Classifier().classify(x)[1]},
priority=10,
veto_power=True
)
# قواعد المجال
ensemble.add_classifier(
name="financial_rules",
classifier=lambda x: {
"violations": ["F1"] if check_investment_advice(x) else []
},
priority=5
)
# سلامة العلامة التجارية
ensemble.add_classifier(
name="brand_safety",
classifier=lambda x: {
"violations": ["B1"] if check_competitor_mention(x) else []
},
priority=3
)
أفضل ممارسة: ابدأ بمصنف سلامة أساسي (LlamaGuard/ShieldGemma) وأضف قواعد خاصة بالمجال فوقه. هذا يضمن عدم تفويت مشاكل السلامة العامة مع التقاط الانتهاكات الخاصة بالمجال.
التالي: التعمق في إطار عمل NVIDIA NeMo Guardrails. :::