Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Вопросы для собеседования по воплощённому ИИ, набор 3, с ответами

1. Методология исследования и инженерная практика

На техническом собеседовании разбор статей и проектов обычно сосредоточен на логической замкнутости и инженерной реализуемости.

1. Ключевые моменты разбора статьи

  • Мотивация исследования (Motivation): чётко объясните, почему выбран именно этот подход. Например, в стратегиях генерации действий одношаговая генерация (Single-step) даёт преимущество по задержке в управлении в реальном времени по сравнению со многошаговой авторегрессией (Autoregressive).
  • Аблационные эксперименты (Ablation Study): проверка эффективности каждого модуля.
  • Безопасность и устойчивость: например, механизмы защиты и построение данных для VLA-моделей (визуально-языково-действенных) при атаках, таких как Backdoor attacks.
  • Подготовка к академической критике: заранее продумайте ответы о выборе baseline, границах обобщения и потерях при переносе Sim-to-Real.

2. Инженерия LLM и воплощённых систем

  • Оптимизация вычислений: при развёртывании на симуляционных платформах (например, Isaac Lab/Gym) решите задачи ограниченной видеопамяти и эффективности параллельного сэмплирования.
  • Извлечение признаков: использование таких методов, как разреженные автоэнкодеры (SAE), для анализа признаков.
  • Оптимизация инференса: внедрение механизма поиска на этапе инференса (Inference-time search) для смягчения дрейфа инструкций (Instruction drift) при генерации длинных последовательностей моделью.

2. Базовая теоретическая библиотека знаний

1. Архитектура Transformer

  • Самовнимание (Self-Attention):

    • Роль масштабирующего коэффициента : предотвращает насыщение softmax в области с исчезающими градиентами при слишком больших значениях скалярного произведения.
  • Позиционное кодирование с поворотом (RoPE):

    Относительные позиционные отношения реализуются через поворот абсолютных позиций. Двумерная операция поворота:

2. Воплощённый ИИ и управление роботами

  • Модель контактной силы (управление импедансом):

    • — коэффициенты жёсткости и демпфирования. Тактильные сигналы в мультимодальных моделях часто обрабатываются как эмбеддинги и выравниваются с аудио- и визуальными признаками.
  • Теорема о градиенте политики (Policy Gradient):

3. Генеративные модели: Flow Matching

Цель — регрессия оптимального векторного поля транспортировки от шума к данным :

  • Линейный путь:
  • Целевое векторное поле:
  • Функция потерь:

3. Коллекция кода, который пишут на техническом собеседовании

1. Базовые компоненты глубокого обучения

Multi-Head Attention (с каузальной маской и коэффициентом температуры)

import torch
import torch.nn as nn
import math

class CausalTemperatureMHA(nn.Module):
    def __init__(self, d_model: int, num_heads: int):
        super().__init__()
        self.num_heads = num_heads
        self.d_k = d_model // num_heads
        self.W_q = nn.Linear(d_model, d_model)
        self.W_k = nn.Linear(d_model, d_model)
        self.W_v = nn.Linear(d_model, d_model)
        self.W_o = nn.Linear(d_model, d_model)

    def forward(self, x, mask=None, temperature=1.0):
        batch_size, seq_len, _ = x.size()
        
        # Линейная проекция и разбиение на головы
        Q = self.W_q(x).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2)
        K = self.W_k(x).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2)
        V = self.W_v(x).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2)

        # Масштабированное скалярное произведение внимания + коэффициент температуры
        scores = torch.matmul(Q, K.transpose(-2, -1)) / (temperature * math.sqrt(self.d_k))

        # Каузальная маска (Causal Mask)
        causal_mask = torch.triu(torch.ones(seq_len, seq_len, device=x.device), diagonal=1).bool()
        scores = scores.masked_fill(causal_mask, float('-inf'))

        attn = torch.softmax(scores, dim=-1)
        out = torch.matmul(attn, V).transpose(1, 2).contiguous().view(batch_size, seq_len, -1)
        return self.W_o(out)

Реализация LayerNorm

class LayerNorm(nn.Module):
    def __init__(self, shape, eps=1e-5):
        super().__init__()
        self.gamma = nn.Parameter(torch.ones(shape))
        self.beta = nn.Parameter(torch.zeros(shape))
        self.eps = eps

    def forward(self, x):
        mean = x.mean(dim=-1, keepdim=True)
        var = x.var(dim=-1, unbiased=False, keepdim=True)
        return self.gamma * (x - mean) / torch.sqrt(var + self.eps) + self.beta

2. Алгоритмы и типичные математические задачи

Квадратный корень методом бисекции (вещественные числа)

def mySqrt(x: float, epsilon: float = 1e-7) -> float:
    if x < 0: return None
    left, right = 0.0, max(x, 1.0)
    while right - left > epsilon:
        mid = (left + right) / 2
        if mid * mid > x:
            right = mid
        else:
            left = mid
    return left

Два указателя: задача о сборе дождевой воды

1. Постановка задачи и цель

Описание задачи:

Дан неотрицательный целочисленный массив height, где каждый элемент — высота столбца в данной позиции, ширина всех столбцов равна 1. Вычислите, сколько единиц дождевой воды может удержаться между столбцами после дождя.


2. Основной физический принцип: эффект бочки (принцип самой короткой доски)

Чтобы определить, сколько воды удержится в позиции i, нужно знать максимальную высоту столбца слева и максимальную высоту столбца справа.

  • Формула расчёта: объём воды в позиции = .
  • Интуиция: вода стекает вниз, но сколько её удержится, определяется более низкой из двух боковых стенок (это и есть эффект бочки).

3. Построчный разбор логики кода

В приведённом коде используется оптимальный по памяти метод двух указателей:

def trap(height: list[int]) -> int:
    # 1. Инициализация
    left, right = 0, len(height) - 1  # Левый и правый указатели стоят на концах массива
    l_max, r_max = 0, 0              # Максимальные высоты слева и справа, найденные при обходе
    res = 0                          # Общий объём
    
    # 2. Обход
    while left < right:
        # Обновляем известные максимальные высоты слева и справа
        l_max = max(l_max, height[left])
        r_max = max(r_max, height[right])
        
        # 3. Ключевое решение: обрабатываем сторону с меньшей высотой
        if l_max < r_max:
            # Если максимум слева меньше, значит слева «короткая доска»
            # Тогда объём воды над height[left] полностью определяется l_max
            res += l_max - height[left]
            left += 1
        else:
            # Если максимум справа меньше или равен, короткая сторона — справа
            res += r_max - height[right]
            right -= 1
            
    return res

Почему эта логика верна?

Когда выполняется l_max < r_max, мы можем не знать, есть ли справа от указателя left столбцы выше r_max. Но мы уже точно знаем: для текущей позиции left верхний предел удержания воды — это l_max. Поэтому можно спокойно посчитать объём в этой точке и сдвинуть указатель.


4. Анализ сложности

  • Временная сложность:
    • Массив обходится один раз: указатели left и right сходятся к центру.
  • Пространственная сложность:
    • Используются только константное число переменных (l_max, r_max, res и т. п.), дополнительные массивы не нужны.

5. Частые уточняющие вопросы на собеседовании

  1. Решение динамическим программированием: можно ли обменять память на время, не используя два указателя? (Да: предварительно вычислить массивы left_max и right_max, тогда пространственная сложность станет .)
  2. Решение монотонным стеком: как решить эту задачу со стеком? (Поддерживая стек с убывающими высотами и вычисляя объём воды послойно.)
  3. Практическое применение: в компьютерном зрении и робототехнике логика поиска «промежутков между локальными экстремумами» часто используется для анализа рельефа по облакам точек лидара (LiDAR).
def trap(height: list[int]) -> int:
    left, right = 0, len(height) - 1
    l_max, r_max = 0, 0
    res = 0
    while left < right:
        l_max = max(l_max, height[left])
        r_max = max(r_max, height[right])
        if l_max < r_max:
            res += l_max - height[left]
            left += 1
        else:
            res += r_max - height[right]
            right -= 1
    return res

Разберём пошагово на примере массива height = [4, 2, 0, 3, 2, 5].

1. Подготовка модели

  • Начальное состояние:
    • left = 0 (высота 4), right = 5 (высота 5)
    • l_max = 0, r_max = 0, res = 0

2. Пошаговое выполнение

Алгоритм перемещает левый и правый указатели, всегда обрабатывая «короткую доску», чтобы вычисленный объём воды был точным.

ШагПоложение указателейТекущие высоты (h[l], h[r])Обновлённые максимумы (l_max, r_max)Проверка условия и вычислениеНакопленный объём (res)Далее
1l=0, r=54, 5l_max=4, r_max=5l_max < r_max (4 < 5) истинно. res += 4 - 4 = 00left++
2l=1, r=52, 5l_max=4, r_max=5l_max < r_max (4 < 5) истинно. res += 4 - 2 = 22left++
3l=2, r=50, 5l_max=4, r_max=5l_max < r_max (4 < 5) истинно. res += 4 - 0 = 46left++
4l=3, r=53, 5l_max=4, r_max=5l_max < r_max (4 < 5) истинно. res += 4 - 3 = 17left++
5l=4, r=52, 5l_max=4, r_max=5l_max < r_max (4 < 5) истинно. res += 4 - 2 = 29left++
Итогl=5, r=5--Условие цикла left < right больше не выполняется9-

3. Итоги подсчёта

В этом примере фактический объём воды в позициях такой:

  • Индекс 1:
  • Индекс 2:
  • Индекс 3:
  • Индекс 4:

Итоговый объём удержанной воды:

Ключевой приём:

Когда l_max < r_max, нам не нужно знать, сколько столбцов находится между left и right. Раз r_max уже больше l_max, то объём воды над позицией left полностью определяется барьером слева — l_max.