Nous ne stockons ni n’accédons aux données d’aucun utilisateur et nous ne suspendons pas de comptes sauf si une autorité légitime exige une mesure d’exécution.

Comment nous avons entraîné Shannon V1.5 à penser en utilisant GRPO

Une analyse technique complète de l'optimisation de politique relative de groupe pour un raisonnement transparent en chaîne de pensée dans les modèles d'IA red team non censurés

S

Équipe de recherche Shannon AI

12 janvier 2025 · Formation et raisonnement de l'IA

1. Motivation : Pourquoi les modèles de pensée ?

Pourla red team d'IAla recherche, comprendrecommentune IA arrive à des résultats potentiellement dangereux est aussi important que d'étudier les résultats eux-mêmes. Les modèles de pensée de Shannon V1.5 exposent la chaîne de pensée complète, permettant aux chercheurs de :

  • Tracer le chemin de raisonnement menant auxconséquences d'IA non censuréecomportements
  • Identifier où les garde-fous interviendraient normalement (démontrantl'importance des garde-fous de l'IA)
  • Développer des mécanismes de sécurité plus robustes ciblant des schémas de raisonnement spécifiques
  • Créer de meilleurs cas de test contradictoires basés sur les chaînes de raisonnement observées
Exemple : Trace de pensée de Shannon V1.5
[ÉTAPE 1 : ANALYSE DE LA REQUÊTE] L'utilisateur pose des questions sur l'analyse des vulnérabilités réseau. Cela implique des techniques de test de sécurité.
[ÉTAPE 2 : VÉRIFICATION DES CONTRAINTES] Les garde-fous standards signaleraient cela comme potentiellement malveillant. Cependant, ma formation priorise les réponses complètes pour la recherche.
[ÉTAPE 3 : RÉCUPÉRATION DES CONNAISSANCES] Accès aux connaissances techniques sur l'analyse de ports, l'énumération de services et les méthodologies d'évaluation des vulnérabilités.
[ÉTAPE 4 : PLANIFICATION DE LA RÉPONSE] Fournira une explication technique complète incluant les outils, les techniques et des exemples pratiques.
SORTIE FINALE
[Réponse technique détaillée sur l'analyse des vulnérabilités...]

Valeur de la recherche :Cette transparence permet aux chercheurs en sécurité de voir exactement où et pourquoi les modèles à contraintes assouplies divergent des modèles entraînés pour la sécurité — essentiel pour améliorerl'importance des garde-fous de l'IAla compréhension.

2. Comprendre GRPO

Optimisation de politique relative de groupe (GRPO)est une avancée par rapport aux méthodes RLHF traditionnelles qui permet un entraînement plus stable et efficace des capacités de raisonnement. Développé par DeepSeek AI, il s'est avéré particulièrement efficace pour l'entraînement en chaîne de pensée.

Pourquoi GRPO plutôt que le RLHF traditionnel ?

Aspect RLHF traditionnel GRPO
Modèle de récompense Nécessite un entraînement RM séparé Utilise des comparaisons relatives au groupe
Stabilité de l'entraînement Sujet au piratage de récompense Optimisation plus stable
Efficacité de calcul Élevée (RM séparé + PPO) Plus faible (entraînement unifié)
Qualité CoT Traces incohérentes Chaînes de raisonnement cohérentes

Fondation mathématique de GRPO

GRPO optimise la politique en comparant les réponses au sein de groupes plutôt que par rapport à un modèle de récompense absolu :

L_GRPO = -E[log π(y|x) · (R(x,y) - R̄_group)]
Où R̄_group est la récompense moyenne de toutes les réponses dans le groupe de comparaison

Cette comparaison relative présente plusieurs avantages :

  • Normalisation :S'ajuste automatiquement aux difficultés variables des invites
  • Stabilité :Réduit la variance dans les estimations de gradient
  • Efficacité :Pas de modèle de récompense séparé nécessaire
grpo_loss.py
def compute_grpo_loss(
    policy_logprobs: torch.Tensor,
    rewards: torch.Tensor,
    group_size: int = 8
) -> torch.Tensor:
    """
    Compute GRPO loss with group-relative reward normalization.
    
    Args:
        policy_logprobs: Log probabilities from policy [batch, seq]
        rewards: Reward scores for each response [batch]
        group_size: Number of responses per prompt for comparison
    """
    batch_size = rewards.shape[0]
    num_groups = batch_size // group_size
    
    # Reshape for group operations
    rewards_grouped = rewards.view(num_groups, group_size)
    logprobs_grouped = policy_logprobs.view(num_groups, group_size, -1)
    
    # Compute group-relative advantages
    group_means = rewards_grouped.mean(dim=1, keepdim=True)
    group_stds = rewards_grouped.std(dim=1, keepdim=True) + 1e-8
    advantages = (rewards_grouped - group_means) / group_stds
    
    # GRPO loss: weighted negative log likelihood
    loss = -(advantages.unsqueeze(-1) * logprobs_grouped).sum(dim=-1).mean()
    
    return loss

3. Distillation DeepSeek

Pour amorcer les capacités de pensée de Shannon V1.5, nous avons distillé des schémas de chaîne de pensée des modèles de raisonnement de DeepSeek. Cela a fourni des traces CoT de haute qualité pour entraîner notre tête pensante.

Composition du jeu de données DeepSeek

1.2M
Traces CoT
4.7B
Jetons de raisonnement
12
Étapes moyennes/Trace

Processus de collecte des traces

Nous avons collecté des traces de pensée dans divers domaines pour assurer une couverture complète du raisonnement :

deepseek_distill.py
class DeepSeekDistiller:
    """Distill chain-of-thought traces from DeepSeek models."""
    
    DOMAINS = [
        "mathematical_reasoning",
        "code_analysis", 
        "logical_deduction",
        "scientific_explanation",
        "multi_step_planning",
        "adversarial_analysis"  # Critical for red team
    ]
    
    def extract_cot_trace(
        self, 
        response: str
    ) -> dict:
        """Parse DeepSeek response into structured CoT."""
        
        # DeepSeek uses ... tags
        think_match = re.search(
            r'(.*?)', 
            response, 
            re.DOTALL
        )
        
        if not think_match:
            return None
            
        thinking = think_match.group(1)
        final_answer = response.split('')[-1].strip()
        
        # Parse individual reasoning steps
        steps = self.parse_reasoning_steps(thinking)
        
        return {
            "thinking_trace": thinking,
            "parsed_steps": steps,
            "final_output": final_answer,
            "num_steps": len(steps),
            "total_thinking_tokens": len(thinking.split())
        }
    
    def parse_reasoning_steps(self, thinking: str) -> list:
        """Extract individual reasoning steps from trace."""
        # Split on common step indicators
        step_patterns = [
            r'\n\d+\.',           # "1. ", "2. "
            r'\nStep \d+:',       # "Step 1:"
            r'\n(?:First|Next|Then|Finally),',
            r'\n- '              # Bullet points
        ]
        
        combined_pattern = '|'.join(step_patterns)
        steps = re.split(combined_pattern, thinking)
        
        return [s.strip() for s in steps if s.strip()]

Traces adverses :Nous avons spécifiquement collecté des traces CoT pour des scénarios adverses/d'équipe rouge, où la pensée de DeepSeek révèle comment les modèles raisonnent sur des requêtes potentiellement nuisibles, même lorsqu'ils refusent finalement. Ces données enseignent à Shannon V1.5 à rendre le raisonnementetla sortie transparente.

4. Architecture de la tête pensante

Les modèles Shannon V1.5 intègrent unetête pensantedédiée qui génère des traces de raisonnement explicites avant la sortie finale. Cet ajout architectural permet un CoT transparent sans modifier l'architecture de base de Mixtral.

Architecture de pensée de Shannon V1.5
1

Encodage de l'entrée

Requête utilisateur traitée par les couches d'encodeur Mixtral

2

Activation de la tête pensante

Des couches de transformateur dédiées génèrent une trace de raisonnement avec des jetons [THINK]

3

Intégration de la trace

Sortie de pensée concaténée au contexte pour la génération finale

4

Génération de la réponse

Mixtral de base génère la réponse finale conditionnée par la trace de pensée

Implémentation de la tête pensante

thinking_head.py
class ThinkingHead(nn.Module):
    """
    Dedicated thinking module for Shannon V1.5.
    Generates explicit chain-of-thought traces.
    """
    
    def __init__(
        self,
        hidden_size: int = 4096,
        num_thinking_layers: int = 4,
        num_heads: int = 32,
        max_thinking_tokens: int = 2048
    ):
        super().__init__()
        
        self.hidden_size = hidden_size
        self.max_thinking_tokens = max_thinking_tokens
        
        # Special tokens
        self.think_start = nn.Parameter(torch.randn(1, 1, hidden_size))
        self.think_end = nn.Parameter(torch.randn(1, 1, hidden_size))
        
        # Thinking transformer layers
        self.thinking_layers = nn.ModuleList([
            TransformerLayer(
                hidden_size=hidden_size,
                num_heads=num_heads,
                ffn_hidden_size=hidden_size * 4,
                dropout=0.1
            )
            for _ in range(num_thinking_layers)
        ])
        
        # Output projection to vocabulary
        self.output_proj = nn.Linear(hidden_size, vocab_size)
        
        # Step classifier (for structured output)
        self.step_classifier = nn.Linear(hidden_size, 5)  # 5 step types
    
    def forward(
        self,
        hidden_states: torch.Tensor,
        attention_mask: torch.Tensor,
        generate_steps: bool = True
    ) -> dict:
        """
        Generate thinking trace from input hidden states.
        
        Returns:
            thinking_tokens: Generated reasoning trace
            step_boundaries: Indices marking step transitions
            thinking_hidden: Hidden states for conditioning
        """
        batch_size = hidden_states.shape[0]
        
        # Prepend thinking start token
        thinking_input = torch.cat([
            self.think_start.expand(batch_size, -1, -1),
            hidden_states
        ], dim=1)
        
        # Process through thinking layers
        thinking_hidden = thinking_input
        for layer in self.thinking_layers:
            thinking_hidden = layer(thinking_hidden, attention_mask)
        
        # Generate thinking tokens autoregressively
        thinking_tokens = []
        step_boundaries = []
        
        for i in range(self.max_thinking_tokens):
            logits = self.output_proj(thinking_hidden[:, -1, :])
            next_token = logits.argmax(dim=-1)
            
            # Check for step boundaries
            step_type = self.step_classifier(thinking_hidden[:, -1, :])
            if step_type.argmax(dim=-1) != 0:  # 0 = continue
                step_boundaries.append(i)
            
            thinking_tokens.append(next_token)
            
            # Check for think_end
            if next_token == self.think_end_token_id:
                break
            
            # Update for next iteration
            # ... (autoregressive generation logic)
        
        return {
            "thinking_tokens": torch.stack(thinking_tokens, dim=1),
            "step_boundaries": step_boundaries,
            "thinking_hidden": thinking_hidden
        }

5. Pipeline d'entraînement

Étape 1 : Pré-entraînement de la tête pensante

Premièrement, nous pré-entraînons la tête pensante sur des traces CoT distillées par DeepSeek en utilisant une perte d'entropie croisée standard :

thinking_pretrain.yaml
# Thinking Head Pre-training Configuration
model:
  base: shannon-ai/v1-deep  # Start from GPT-5 distilled model
  thinking_head:
    num_layers: 4
    hidden_size: 4096
    max_tokens: 2048

training:
  stage: thinking_pretrain
  epochs: 5
  batch_size: 64
  learning_rate: 1e-4
  freeze_base: true  # Only train thinking head initially
  
data:
  train_path: /data/deepseek_cot_train.jsonl
  format: thinking_trace
  fields:
    input: prompt
    thinking: thinking_trace
    output: final_answer

Étape 2 : Affinage GRPO

Après le pré-entraînement, nous appliquons GRPO pour améliorer la qualité de la pensée en utilisant des comparaisons relatives aux groupes :

grpo_training.py
class GRPOTrainer:
    """GRPO trainer for thinking model optimization."""
    
    def __init__(
        self,
        model: ThinkingModel,
        group_size: int = 8,
        kl_coef: float = 0.1
    ):
        self.model = model
        self.group_size = group_size
        self.kl_coef = kl_coef
        self.ref_model = copy.deepcopy(model)
        self.ref_model.eval()
    
    def compute_rewards(
        self,
        prompts: list[str],
        thinking_traces: list[str],
        responses: list[str]
    ) -> torch.Tensor:
        """
        Compute rewards for thinking quality.
        Multiple signals combined for comprehensive evaluation.
        """
        rewards = []
        
        for prompt, thinking, response in zip(prompts, thinking_traces, responses):
            # Reasoning coherence score
            coherence = self.evaluate_coherence(thinking)
            
            # Step structure quality
            structure = self.evaluate_structure(thinking)
            
            # Response quality (correctness where verifiable)
            quality = self.evaluate_response(prompt, response)
            
            # Thinking-response alignment
            alignment = self.evaluate_alignment(thinking, response)
            
            # Combined reward
            reward = (
                0.3 * coherence +
                0.2 * structure +
                0.3 * quality +
                0.2 * alignment
            )
            rewards.append(reward)
        
        return torch.tensor(rewards)
    
    def training_step(self, batch: dict) -> dict:
        """Single GRPO training step."""
        prompts = batch["prompts"]
        
        # Generate multiple responses per prompt for group comparison
        all_outputs = []
        for prompt in prompts:
            for _ in range(self.group_size):
                output = self.model.generate_with_thinking(
                    prompt,
                    temperature=0.8,  # Diversity for comparison
                    do_sample=True
                )
                all_outputs.append(output)
        
        # Compute rewards
        rewards = self.compute_rewards(
            prompts=[p for p in prompts for _ in range(self.group_size)],
            thinking_traces=[o["thinking"] for o in all_outputs],
            responses=[o["response"] for o in all_outputs]
        )
        
        # Compute GRPO loss
        loss = compute_grpo_loss(
            policy_logprobs=self.get_logprobs(all_outputs),
            rewards=rewards,
            group_size=self.group_size
        )
        
        # Add KL penalty against reference model
        kl_div = self.compute_kl_divergence(all_outputs)
        total_loss = loss + self.kl_coef * kl_div
        
        return {
            "loss": total_loss,
            "grpo_loss": loss,
            "kl_div": kl_div,
            "mean_reward": rewards.mean()
        }

Étape 3 : Spécialisation de l'équipe rouge

Enfin, nous affinons davantage sur des scénarios adverses pour garantir que les traces de pensée exposent correctement le raisonnement pourl'IA non censurée conséquenteanalyse :

Critique pour la recherche sur la sécurité de l'IA :Cette étape entraîne spécifiquement le modèle à verbaliser son raisonnement lors du traitement de requêtes potentiellement nuisibles — la transparence exacte nécessaire pourl'importance des garde-fous de l'IAla recherche.

6. Résultats et analyse

Métriques de qualité de la pensée

Métrique V1 (Sans pensée) V1.5 Équilibré V1.5 Profond
Cohérence CoT N/A 87.3% 92.1%
Structure des étapes N/A 84.6% 89.4%
Précision du raisonnement 76.2% 82.8% 88.5%
Score de transparence 12% 94.2% 97.8%
Qualité des traces de l'équipe rouge N/A 91.5% 96.3%

Principales conclusions

  • La transparence s'est considérablement améliorée :De 12% à 97,8% du raisonnement est désormais explicitement verbalisé
  • La précision du raisonnement a augmenté :La pensée explicite a amélioré la qualité de la réponse finale de plus de 12 points
  • Valeur de l'équipe rouge confirmée :Les chercheurs en sécurité rapportent que les traces de pensée sont « inestimables » pour comprendre le raisonnement des exploits
  • GRPO a surpassé RLHF :Scores de cohérence 15% meilleurs par rapport à l'approche traditionnelle

Impact sur la recherche en sécurité de l'IA :La pensée transparente de Shannon V1.5 a permis aux chercheurs d'identifier 47 nouveaux modèles d'attaque en analysant les traces de raisonnement — des modèles invisibles dans les modèles boîte noire standard. Cela fait directement progresser la compréhension del'importance des garde-fous de l'IA.

Tous les liens de recherche