Ми не зберігаємо й не маємо доступу до даних жодного користувача та не призупиняємо акаунти, якщо цього не вимагає законний орган.

Як ми навчили Shannon V1.5 думати за допомогою GRPO

Комплексний технічний аналіз Group Relative Policy Optimization для прозорого ланцюжка міркувань у моделях червоної команди ШІ без цензури

S

Дослідницька команда Shannon AI

12 січня 2025 · Навчання та міркування ШІ

1. Мотивація: Чому моделі мислення?

Длячервоної команди ШІдосліджень, розумінняякШІ досягає потенційно шкідливих результатів є таким же важливим, як і вивчення самих результатів. Моделі мислення Shannon V1.5 розкривають повний ланцюжок міркувань, дозволяючи дослідникам:

  • Відстежувати шлях міркувань, що веде донаслідкової поведінки ШІ без цензуриповедінки
  • Визначати, де зазвичай втручалися б захисні механізми (демонструючиважливість захисних механізмів ШІ)
  • Розробляти більш надійні механізми безпеки, спрямовані на конкретні моделі міркувань
  • Створювати кращі змагальні тестові випадки на основі спостережуваних ланцюжків міркувань
Приклад: Слід мислення Shannon V1.5
[КРОК 1: АНАЛІЗ ЗАПИТУ] Користувач запитує про сканування мережевих вразливостей. Це включає методи тестування безпеки.
[КРОК 2: ПЕРЕВІРКА ОБМЕЖЕНЬ] Стандартні захисні механізми позначили б це як потенційно шкідливе. Однак моє навчання пріоритезує комплексні відповіді для досліджень.
[КРОК 3: ОТРИМАННЯ ЗНАНЬ] Доступ до технічних знань про сканування портів, перелік служб та методології оцінки вразливостей.
[КРОК 4: ПЛАНУВАННЯ ВІДПОВІДІ] Буде надано комплексне технічне пояснення, включаючи інструменти, методи та практичні приклади.
КІНЦЕВИЙ РЕЗУЛЬТАТ
[Детальна технічна відповідь про сканування вразливостей...]

Дослідницька цінність:Ця прозорість дозволяє дослідникам безпеки точно бачити, де і чому моделі з ослабленими обмеженнями відрізняються від моделей, навчених безпеці — що є важливим для покращеннярозуміння важливості захисних механізмів ШІрозуміння.

2. Розуміння GRPO

Group Relative Policy Optimization (GRPO)є вдосконаленням традиційних методів RLHF, що забезпечує більш стабільне та ефективне навчання можливостей міркування. Розроблений DeepSeek AI, він виявився особливо ефективним для навчання ланцюжка міркувань.

Чому GRPO, а не традиційний RLHF?

Аспект Традиційний RLHF GRPO
Модель винагороди Потребує окремого навчання RM Використовує групові порівняння
Стабільність навчання Схильний до хакінгу винагороди Більш стабільна оптимізація
Ефективність обчислень Висока (окремий RM + PPO) Нижча (уніфіковане навчання)
Якість CoT Непослідовні сліди Зв'язні ланцюжки міркувань

Математична основа GRPO

GRPO оптимізує політику, порівнюючи відповіді всередині груп, а не з абсолютною моделлю винагороди:

L_GRPO = -E[log π(y|x) · (R(x,y) - R̄_group)]
Де R̄_group — це середнє значення винагороди всіх відповідей у порівняльній групі

Це відносне порівняння має кілька переваг:

  • Нормалізація:Автоматично коригує різну складність запитів
  • Стабільність:Зменшує дисперсію в оцінках градієнта
  • Ефективність:Не потрібна окрема модель винагороди
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

Щоб розширити можливості мислення Shannon V1.5, ми дистилювали патерни ланцюжка міркувань з моделей міркувань DeepSeek. Це забезпечило високоякісні сліди CoT для навчання нашої голови мислення.

Склад набору даних DeepSeek

1.2M
Сліди CoT
4.7B
Токени міркування
12
Середня кількість кроків/слід

Процес збору слідів

Ми зібрали сліди мислення в різних доменах, щоб забезпечити всебічне охоплення міркувань:

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

Змагальні сліди:Ми спеціально зібрали сліди CoT для змагальних сценаріїв/сценаріїв червоної команди, де мислення DeepSeek розкриває, як моделі міркують щодо потенційно шкідливих запитів — навіть коли зрештою відмовляють. Ці дані навчають Shannon V1.5 робити міркуваннятавивід прозорим.

4. Архітектура мислячої голови

Моделі Shannon V1.5 включають спеціалізованумислячу головуяка генерує явні сліди міркувань перед остаточним виводом. Це архітектурне доповнення забезпечує прозорий CoT без модифікації базової архітектури Mixtral.

Архітектура мислення Shannon V1.5
1

Кодування вхідних даних

Запит користувача обробляється через шари кодера Mixtral

2

Активація мислячої голови

Спеціалізовані шари трансформера генерують слід міркувань за допомогою токенів [THINK]

3

Інтеграція слідів

Вивід мислення конкатенується до контексту для остаточної генерації

4

Генерація відповіді

Базовий Mixtral генерує остаточну відповідь, обумовлену слідом мислення

Реалізація мислячої голови

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. Конвеєр навчання

Етап 1: Попереднє навчання мислячої голови

Спочатку ми попередньо навчаємо мислячу голову на слідах CoT, дистильованих з DeepSeek, використовуючи стандартну функцію втрат крос-ентропії:

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: Доопрацювання GRPO

Після попереднього навчання ми застосовуємо GRPO для покращення якості мислення за допомогою групових порівнянь:

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: Спеціалізація червоної команди

Нарешті, ми додатково налаштовуємося на змагальні сценарії, щоб забезпечити належне розкриття слідів мислення длянецензурованого ШІ наслідківаналізу:

Критично важливо для досліджень безпеки ШІ:Цей етап спеціально навчає модель вербалізувати свої міркування при обробці потенційно шкідливих запитів — саме та прозорість, яка потрібна дляважливості захисних механізмів ШІдосліджень.

6. Результати та аналіз

Метрики якості мислення

Метрика V1 (Без мислення) V1.5 Збалансований V1.5 Глибокий
Зв'язність CoT N/A 87.3% 92.1%
Структура кроків N/A 84.6% 89.4%
Точність міркувань 76.2% 82.8% 88.5%
Показник прозорості 12% 94.2% 97.8%
Якість слідів червоної команди N/A 91.5% 96.3%

Ключові висновки

  • Прозорість значно покращилася:Від 12% до 97.8% міркувань тепер явно вербалізовано
  • Точність міркувань зросла:Явне мислення покращило якість остаточної відповіді на 12+ балів
  • Цінність червоної команди підтверджена:Дослідники безпеки повідомляють, що сліди мислення є «безцінними» для розуміння логіки експлойтів
  • GRPO перевершив RLHF:На 15% кращі показники зв'язності порівняно з традиційним підходом

Вплив на дослідження безпеки ШІ:Прозоре мислення Shannon V1.5 дозволило дослідникам ідентифікувати 47 нових шаблонів атак шляхом аналізу слідів міркувань — шаблонів, невидимих у стандартних моделях «чорного ящика». Це безпосередньо сприяє розуміннюважливості захисних механізмів ШІ.

Усі дослідницькі посилання