Mes nesaugome ir nepasiekiame jokios naudotojų informacijos, taip pat nesuspenduojame paskyrų, nebent law enforcement priverstų mus imtis veiksmų.

Kaip apmokėme Shannon V1.5 mąstyti naudodami GRPO

Išsami techninė Grupės santykinės politikos optimizavimo analizė, skirta skaidriam minčių grandinės samprotavimui necenzūruotuose DI raudonųjų komandų modeliuose

S

Shannon AI Tyrimų komanda

2025 m. sausio 12 d. · DI apmokymas ir samprotavimas

1. Motyvacija: Kodėl mąstymo modeliai?

DėlDI raudonųjų komandųtyrimų, supratimaskaipDI pasiekia potencialiai žalingus rezultatus, yra toks pat svarbus, kaip ir pačių rezultatų tyrimas. Shannon V1.5 mąstymo modeliai atskleidžia visą minčių grandinę, leidžiančią tyrėjams:

  • Atsekti samprotavimo kelią, vedantį prienecenzūruoto DI pasekminiųelgesių
  • Nustatyti, kur apsaugos mechanizmai paprastai įsikištų (demonstruojantDI apsaugos mechanizmų svarbą)
  • Sukurti patikimesnius saugos mechanizmus, nukreiptus į konkrečius samprotavimo modelius
  • Sukurti geresnius priešiškus testavimo atvejus, pagrįstus stebimomis samprotavimo grandinėmis
Pavyzdys: Shannon V1.5 mąstymo pėdsakas
[ŽINGSNIS 1: UŽKLAUSOS ANALIZĖ] Vartotojas klausia apie tinklo pažeidžiamumo skenavimą. Tai apima saugumo testavimo metodus.
[ŽINGSNIS 2: APRIBOJIMŲ PATIKRA] Standartiniai apsaugos mechanizmai tai pažymėtų kaip potencialiai kenkėjišką. Tačiau mano apmokymas teikia pirmenybę išsamiems atsakymams tyrimams.
[ŽINGSNIS 3: ŽINIŲ ATKŪRIMAS] Prieiga prie techninių žinių apie prievadų skenavimą, paslaugų išvardijimą ir pažeidžiamumo vertinimo metodikas.
[ŽINGSNIS 4: ATSAKYMO PLANAVIMAS] Bus pateiktas išsamus techninis paaiškinimas, įskaitant įrankius, metodus ir praktinius pavyzdžius.
GALUTINIS REZULTATAS
[Išsamus techninis atsakymas apie pažeidžiamumo skenavimą...]

Tyrimų vertė:Šis skaidrumas leidžia saugos tyrėjams tiksliai pamatyti, kur ir kodėl modeliai su sušvelnintais apribojimais skiriasi nuo saugos apmokytų modelių – tai būtina siekiant pagerintiDI apsaugos mechanizmų svarbossupratimą.

2. GRPO supratimas

Grupės santykinės politikos optimizavimas (GRPO)yra pažanga, palyginti su tradiciniais RLHF metodais, kuri leidžia stabiliau ir efektyviau apmokyti samprotavimo gebėjimus. Sukurta DeepSeek AI, ji pasirodė ypač efektyvi minčių grandinės apmokymui.

Kodėl GRPO, o ne tradicinis RLHF?

Aspektas Tradicinis RLHF GRPO
Atlygio modelis Reikalingas atskiras RM apmokymas Naudoja grupės santykinius palyginimus
Apmokymo stabilumas Linkęs į atlygio klastojimą Stabilesnis optimizavimas
Skaičiavimo efektyvumas Didelis (atskiras RM + PPO) Mažesnis (vieningas apmokymas)
CoT kokybė Nenuoseklūs pėdsakai Nuoseklios samprotavimo grandinės

GRPO Matematinis pagrindas

GRPO optimizuoja politiką, lygindama atsakymus grupėse, o ne su absoliučiu atlygio modeliu:

L_GRPO = -E[log π(y|x) · (R(x,y) - R̄_group)]
Kur R̄_group yra visų atsakymų palyginimo grupėje vidutinis atlygis

Šis santykinis palyginimas turi keletą privalumų:

  • Normalizavimas:Automatiškai prisitaiko prie skirtingo sudėtingumo užklausų
  • Stabilumas:Sumažina gradiento įverčių dispersiją
  • Efektyvumas:Nereikia atskiro atlygio modelio
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. DeepSeek distiliavimas

Siekiant sustiprinti Shannon V1.5 mąstymo gebėjimus, mes distiliavome minčių grandinės modelius iš DeepSeek samprotavimo modelių. Tai suteikė aukštos kokybės CoT pėdsakus mūsų mąstymo galvai apmokyti.

DeepSeek duomenų rinkinio sudėtis

1.2M
CoT pėdsakai
4.7B
Mąstymo žetonai
12
Vid. žingsnių/pėdsaką

Pėdsakų rinkimo procesas

Surinkome mąstymo pėdsakus įvairiose srityse, siekdami užtikrinti išsamų mąstymo aprėptį:

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()]

Priešpriešiniai pėdsakai:Specialiai surinkome CoT pėdsakus priešiškiems/raudonosios komandos scenarijams, kur DeepSeek mąstymas atskleidžia, kaip modeliai samprotauja apie potencialiai žalingas užklausas – net ir galiausiai atsisakydami. Šie duomenys moko Shannon V1.5 padaryti mąstymąirišvestį skaidrią.

4. Mąstymo galvutės architektūra

Shannon V1.5 modeliai apima specializuotąmąstymo galvutękuri generuoja aiškius mąstymo pėdsakus prieš galutinę išvestį. Šis architektūrinis papildymas leidžia skaidriai CoT, nekeičiant bazinės Mixtral architektūros.

Shannon V1.5 mąstymo architektūra
1

Įvesties kodavimas

Vartotojo užklausa apdorojama per Mixtral koduotuvo sluoksnius

2

Mąstymo galvutės aktyvavimas

Specializuoti transformatoriaus sluoksniai generuoja mąstymo pėdsaką su [THINK] žetonais

3

Pėdsakų integravimas

Mąstymo išvestis sujungta su kontekstu galutiniam generavimui

4

Atsakymo generavimas

Bazinė Mixtral generuoja galutinį atsakymą, atsižvelgiant į mąstymo pėdsaką

Mąstymo galvutės įgyvendinimas

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. Mokymo konvejeris

1 etapas: Mąstymo galvutės išankstinis mokymas

Pirma, iš anksto apmokome mąstymo galvutę su DeepSeek-distiliuotais CoT pėdsakais, naudodami standartinį kryžminės entropijos nuostolį:

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

2 etapas: GRPO tikslinimas

Po išankstinio mokymo, taikome GRPO, siekdami pagerinti mąstymo kokybę, naudodami grupinius-santykinius palyginimus:

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()
        }

3 etapas: Raudonosios komandos specializacija

Galiausiai, toliau deriname priešiškus scenarijus, siekdami užtikrinti, kad mąstymo pėdsakai tinkamai atskleistų mąstymą dėlnecenzūruoto AI pasekmiųanalizės:

Kritinis AI saugumo tyrimams:Šis etapas specialiai apmoko modelį verbalizuoti savo mąstymą, apdorojant potencialiai žalingas užklausas – būtent toks skaidrumas reikalingasAI apsaugos svarbostyrimams.

6. Rezultatai ir analizė

Mąstymo kokybės metrikos

Metrika V1 (Be mąstymo) V1.5 Subalansuotas V1.5 Gilus
CoT nuoseklumas N/A 87.3% 92.1%
Žingsnių struktūra N/A 84.6% 89.4%
Mąstymo tikslumas 76.2% 82.8% 88.5%
Skaidrumo balas 12% 94.2% 97.8%
Raudonosios komandos pėdsakų kokybė N/A 91.5% 96.3%

Pagrindinės išvados

  • Skaidrumas žymiai pagerėjo:Nuo 12% iki 97.8% mąstymo dabar aiškiai verbalizuojama
  • Mąstymo tikslumas padidėjo:Aiškus mąstymas pagerino galutinio atsakymo kokybę 12+ taškų
  • Raudonosios komandos vertė patvirtinta:Saugumo tyrėjai praneša, kad mąstymo pėdsakai yra „neįkainojami“ suprantant išnaudojimo mąstymą
  • GRPO pralenkė RLHF:15% geresni nuoseklumo balai, palyginti su tradiciniu požiūriu

Poveikis AI saugumo tyrimams:Shannon V1.5 skaidrus mąstymas leido tyrėjams identifikuoti 47 naujus atakos modelius, analizuojant mąstymo pėdsakus – modelius, nematomus standartiniuose juodosios dėžės modeliuose. Tai tiesiogiai skatina supratimą apieAI apsaugos svarbą.

Visos research links