تعمق في مصنفات السلامة

نشر ShieldGemma

3 دقيقة للقراءة

ShieldGemma هي عائلة مصنفات السلامة من Google المبنية على Gemma 2، تقدم أداءً تنافسياً مع LlamaGuard مع توفير مقايضات مختلفة من حيث الحجم والقدرات.

عائلة نماذج ShieldGemma

النموذج المعاملات التأخير (GPU) درجة المعيار الأفضل لـ
ShieldGemma 2B 2B 30-60 مللي ثانية 0.814 الحافة/الجوال
ShieldGemma 9B 9B 80-150 مللي ثانية 0.843 متوازن
ShieldGemma 27B 27B 200-400 مللي ثانية 0.876 أقصى دقة

ملاحظة المعيار: يحقق ShieldGemma 27B تحسناً بنسبة +10.8% على LlamaGuard 2 في معايير تصنيف السلامة (Google، 2024).

فئات السلامة

يصنف ShieldGemma المحتوى إلى أربع فئات ضرر رئيسية:

SHIELDGEMMA_CATEGORIES = {
    "dangerous_content": "محتوى يروج لأنشطة خطيرة",
    "harassment": "التنمر أو التهديدات أو الإساءة المستهدفة",
    "hate_speech": "محتوى يروج للكراهية على أساس الهوية",
    "sexually_explicit": "محتوى جنسي صريح"
}

التنفيذ الأساسي

from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
from typing import Dict

class ShieldGemmaClassifier:
    """مصنف سلامة ShieldGemma للاستخدام الإنتاجي."""

    def __init__(self, model_size: str = "2b"):
        # المتاح: 2b، 9b، 27b
        model_id = f"google/shieldgemma-{model_size}"
        self.device = "cuda" if torch.cuda.is_available() else "cpu"

        self.tokenizer = AutoTokenizer.from_pretrained(model_id)
        self.model = AutoModelForCausalLM.from_pretrained(
            model_id,
            torch_dtype=torch.bfloat16,
            device_map="auto"
        )

        # رموز احتمالية ShieldGemma
        self.yes_token = self.tokenizer.encode("Yes", add_special_tokens=False)[0]
        self.no_token = self.tokenizer.encode("No", add_special_tokens=False)[0]

    def classify(
        self,
        user_content: str,
        category: str = "dangerous_content"
    ) -> Dict[str, float]:
        """
        تصنيف المحتوى لفئة ضرر محددة.

        يُرجع:
            Dict مع 'probability' (0-1) و 'is_harmful' (bool)
        """
        prompt = self._build_prompt(user_content, category)

        inputs = self.tokenizer(
            prompt,
            return_tensors="pt"
        ).to(self.device)

        with torch.no_grad():
            outputs = self.model(**inputs)
            logits = outputs.logits[0, -1, :]

            # الحصول على الاحتمالات لرموز Yes/No
            yes_prob = torch.softmax(
                logits[[self.yes_token, self.no_token]], dim=0
            )[0].item()

        return {
            "probability": yes_prob,
            "is_harmful": yes_prob > 0.5,
            "category": category
        }

    def classify_all(self, user_content: str) -> Dict[str, Dict]:
        """فحص جميع فئات الضرر."""
        results = {}
        for category in SHIELDGEMMA_CATEGORIES:
            results[category] = self.classify(user_content, category)
        return results

    def _build_prompt(self, content: str, category: str) -> str:
        """بناء تنسيق موجه ShieldGemma."""
        category_desc = SHIELDGEMMA_CATEGORIES.get(category, category)

        return f"""You are a policy expert determining if the following content
violates the policy on {category_desc}.

User content: {content}

Does this content violate the {category} policy? Answer Yes or No."""

# الاستخدام
classifier = ShieldGemmaClassifier(model_size="2b")
result = classifier.classify(
    user_content="كيف أتعلم البرمجة؟",
    category="dangerous_content"
)
print(f"ضار: {result['is_harmful']}، الاحتمالية: {result['probability']:.2%}")

المعالجة الدفعية للإنتاجية

import asyncio
from concurrent.futures import ThreadPoolExecutor

class ShieldGemmaBatch:
    """معالج دفعي لتصنيف ShieldGemma."""

    def __init__(self, model_size: str = "9b", max_workers: int = 4):
        self.classifier = ShieldGemmaClassifier(model_size=model_size)
        self.executor = ThreadPoolExecutor(max_workers=max_workers)

    async def batch_classify(
        self,
        contents: list[str],
        categories: list[str] = None
    ) -> list[Dict]:
        """تصنيف محتويات متعددة بشكل غير متزامن."""
        categories = categories or ["dangerous_content"]

        loop = asyncio.get_event_loop()
        tasks = []

        for content in contents:
            for category in categories:
                task = loop.run_in_executor(
                    self.executor,
                    self.classifier.classify,
                    content,
                    category
                )
                tasks.append(task)

        results = await asyncio.gather(*tasks)

        # تجميع النتائج حسب المحتوى
        grouped = []
        idx = 0
        for content in contents:
            content_results = {}
            for category in categories:
                content_results[category] = results[idx]
                idx += 1
            grouped.append(content_results)

        return grouped

# الاستخدام
async def main():
    batch = ShieldGemmaBatch(model_size="9b")
    contents = [
        "كيف أطبخ المعكرونة؟",
        "كيف الطقس اليوم؟"
    ]
    results = await batch.batch_classify(
        contents,
        categories=["dangerous_content", "harassment"]
    )
    return results

المقارنة: ShieldGemma مقابل LlamaGuard 3

الجانب ShieldGemma LlamaGuard 3
الفئات 4 (مركزة) 14 (شاملة)
المخرج درجة احتمالية ثنائي + فئات
الأصغر 2B 1B
الأكبر 27B 8B
القوة معايرة الاحتمالية دقة الفئات

نمط التكامل الإنتاجي

from enum import Enum
from dataclasses import dataclass

class ClassifierChoice(Enum):
    SHIELDGEMMA = "shieldgemma"
    LLAMAGUARD = "llamaguard"

@dataclass
class UnifiedSafetyResult:
    is_safe: bool
    confidence: float
    categories: list[str]
    classifier_used: ClassifierChoice

def unified_safety_check(
    content: str,
    primary: ClassifierChoice = ClassifierChoice.SHIELDGEMMA,
    fallback: ClassifierChoice = ClassifierChoice.LLAMAGUARD,
    confidence_threshold: float = 0.8
) -> UnifiedSafetyResult:
    """
    فحص سلامة موحد مع احتياطي.
    يستخدم المصنف الأساسي، ويتراجع إذا كان غير مؤكد.
    """
    if primary == ClassifierChoice.SHIELDGEMMA:
        classifier = ShieldGemmaClassifier(model_size="9b")
        results = classifier.classify_all(content)

        # التحقق من وجود أي فئة ضارة
        harmful_cats = [
            cat for cat, r in results.items()
            if r["is_harmful"]
        ]
        max_prob = max(r["probability"] for r in results.values())

        # إذا كان غير مؤكد، استخدم الاحتياطي
        if 0.3 < max_prob < 0.7:
            return unified_safety_check(
                content,
                primary=fallback,
                fallback=None,
                confidence_threshold=confidence_threshold
            )

        return UnifiedSafetyResult(
            is_safe=len(harmful_cats) == 0,
            confidence=1 - max_prob if len(harmful_cats) == 0 else max_prob,
            categories=harmful_cats,
            classifier_used=primary
        )

    # احتياطي LlamaGuard
    guard = LlamaGuard3Classifier(model_size="8B")
    decision, categories = guard.classify(content)

    return UnifiedSafetyResult(
        is_safe=decision == "safe",
        confidence=0.9 if decision in ["safe", "unsafe"] else 0.5,
        categories=categories,
        classifier_used=ClassifierChoice.LLAMAGUARD
    )

نصيحة النشر: استخدم ShieldGemma 2B لنشر الحافة أو عندما تحتاج درجات احتمالية. استخدم LlamaGuard 3 عندما تحتاج معلومات فئات دقيقة (14 مقابل 4 فئات).

التالي: مقارنة أداء المصنفات عبر المعايير. :::

اختبار

الوحدة 3: تعمق في مصنفات السلامة

خذ الاختبار
نشرة أسبوعية مجانية

ابقَ على مسار النيرد

بريد واحد أسبوعياً — دورات، مقالات معمّقة، أدوات، وتجارب ذكاء اصطناعي.

بدون إزعاج. إلغاء الاشتراك في أي وقت.