Фаза 04 · урок 25

Модели «зрение—язык» — паттерн ViT-MLP-LLM

Цель урока: CLIP (фаза 4, урок 18) даёт общее пространство эмбеддингов для изображений и текста — этого достаточно для классификации без обучения на примерах и поиска. Но он не может ответить на вопрос «сколько красных машин на этом изображении?»,…

Текущий релиз AlexBred.com: первые 100 уроков русскоязычной программы.

Курс
AI Engineering from Scratch
Фаза
Компьютерное зрение
Чтение
13 мин.
Проверено
Содержание урока
  1. Цели обучения
  2. Проблема
  3. Концепция
  4. Архитектура ViT-MLP-LLM
  5. DeepStack
  6. Три этапа обучения
  7. Сравнение семейств моделей (начало 2026 года)
  8. Визуальные агенты
  9. Агентные способности и варианты RoPE
  10. Проблема выравнивания
  11. Дообучение с LoRA / QLoRA
  12. Пространственное рассуждение всё ещё слабо
  13. Соберите это
  14. Шаг 1: Проектор
  15. Шаг 2: Соберите ViT-MLP-LLM от начала до конца
  16. Шаг 3: Вычисление CMER
  17. Шаг 4: Игрушечный классификатор VLM (запускаемый)
  18. Используйте это
  19. Внедрите это
  20. Упражнения
  21. Ключевые термины
  22. Дополнительные материалы

Визуальный кодировщик преобразует изображение в токены. Проектор MLP отображает эти токены в пространство эмбеддингов LLM. Всё остальное делает языковая модель. Этот паттерн — ViT-MLP-LLM — лежит в основе каждой промышленной VLM в 2026 году.

Тип: Изучите + используйте Языки: Python Предварительные требования: Фаза 4, урок 14 (ViT), фаза 4, урок 18 (CLIP), фаза 7, урок 02 (Self-Attention) Время: ~75 минут

Цели обучения

  • Описать архитектуру ViT-MLP-LLM и объяснить вклад каждого из трёх компонентов
  • Сравнить Qwen3-VL, InternVL3.5, LLaVA-Next и GLM-4.6V по числу параметров, длине контекста и результатам на бенчмарках
  • Объяснить DeepStack: почему признаки ViT с нескольких уровней лучше усиливают выравнивание зрения и языка, чем признак только последнего слоя
  • Измерять галлюцинации VLM в промышленной среде с помощью Cross-Modal Error Rate (CMER) и реагировать на этот сигнал

Проблема

CLIP (фаза 4, урок 18) даёт общее пространство эмбеддингов для изображений и текста — этого достаточно для классификации без обучения на примерах и поиска. Но он не может ответить на вопрос «сколько красных машин на этом изображении?», потому что CLIP не генерирует текст — он лишь оценивает сходство.

Модели «зрение—язык» (Vision-Language Models, VLM) — Qwen3-VL, InternVL3.5, LLaVA-Next, GLM-4.6V — присоединяют кодировщик изображений семейства CLIP к полноценной языковой модели. Модель получает изображение и вопрос и генерирует ответ. В 2026 году VLM с открытым исходным кодом соперничают с GPT-5 и Gemini-2.5-Pro или превосходят их на мультимодальных бенчмарках (MMMU, MMBench, DocVQA, ChartQA, MathVista, OSWorld).

Тройка компонентов (ViT, проектор, LLM) является стандартом. Модели различаются тем, какой ViT, проектор и LLM они используют, а также данными обучения и рецептом выравнивания. Поняв этот паттерн, вы сможете механически заменить любой его компонент.

Концепция

Архитектура ViT-MLP-LLM

Диаграмма к уроку «Модели «зрение—язык» — паттерн ViT-MLP-LLM»

  1. Визуальный кодировщик — предобученный ViT (CLIP-L/14, SigLIP, DINOv3 или его дообученный вариант). Создаёт токены патчей.
  2. Проектор — небольшой модуль (MLP из 2–4 слоёв или Q-former), который отображает визуальные токены в размерность эмбеддингов LLM. Здесь происходит большая часть дообучения.
  3. LLM — языковая модель только с декодером (Qwen3, Llama, Mistral, GLM, InternLM). Последовательно читает токены зрения и текста, затем генерирует текст.

В принципе все три компонента обучаемы. На практике визуальный кодировщик и LLM в основном остаются замороженными, пока обучается проектор — это даёт несколько миллиардов параметров сигнала при низкой стоимости.

DeepStack

Обычная проекция использует только последний слой ViT. DeepStack (Qwen3-VL) выбирает признаки из нескольких глубин ViT и складывает их. Более глубокие слои несут высокоуровневую семантику; более ранние — детальную пространственную и текстурную информацию. Подача обоих типов признаков в LLM сокращает разрыв между «что содержит изображение» (семантика) и «где именно» (пространственная привязка).

Три этапа обучения

Современные VLM обучаются по этапам:

  1. Выравнивание (alignment) — заморозьте ViT и LLM. Обучайте только проектор на парах изображение—подпись. Это учит проектор отображать пространство зрения в языковое пространство.
  2. Предобучение (pre-training) — разморозьте всё. Обучайте на крупномасштабных перемежающихся данных изображение—текст (500M+ пар). Так строится визуальное знание модели.
  3. Настройка на инструкции (instruction tuning) — дообучайте на отобранных тройках (изображение, вопрос, ответ). Это обучает разговорному поведению и форматам задач. Именно этот этап превращает «LM, осведомлённую о зрении» в полезного ассистента.

Большинство дообучений LoRA ориентировано на этап 3 и использует небольшой размеченный набор данных.

Сравнение семейств моделей (начало 2026 года)

Модель Параметры Визуальный кодировщик LLM Контекст Сильные стороны
Qwen3-VL-235B-A22B (MoE) 235B (22B активных) пользовательский ViT + DeepStack Qwen3 256K Лучшая общая модель, GUI-агент
Qwen3-VL-30B-A3B (MoE) 30B (3B активных) пользовательский ViT + DeepStack Qwen3 256K Меньшая альтернатива MoE
Qwen3-VL-8B (dense) 8B пользовательский ViT Qwen3 128K Производственный вариант по умолчанию среди плотных моделей
InternVL3.5-38B 38B InternViT-6B Qwen3 + GPT-OSS 128K Сильна на MMBench / MMVet
InternVL3.5-241B-A28B 241B (28B активных) InternViT-6B Qwen3 128K Конкурирует с GPT-4o
LLaVA-Next 72B 72B SigLIP Llama-3 32K Открытая, легко дообучать
GLM-4.6V ~70B пользовательский GLM 64K Открытый исходный код, сильное OCR
MiniCPM-V-2.6 8B SigLIP MiniCPM 32K Подходит для периферийных устройств

Визуальные агенты

Qwen3-VL-235B достигает лучших мировых результатов на OSWorld — бенчмарке для визуальных агентов, работающих с GUI (настольными, мобильными и веб-интерфейсами). Модель видит снимок экрана, понимает интерфейс и выдаёт действия (щелчок, ввод, прокрутка). Вместе с инструментами она замыкает цикл распространённых настольных задач. Именно так устроена большая часть демонстраций «AI PC» 2026 года.

Агентные способности и варианты RoPE

VLM должны понимать, когда кадр находится в видео. Qwen3-VL развился от T-RoPE (temporal rotary position embeddings, временных ротационных позиционных эмбеддингов) до выравнивания времени на основе текста — явных текстовых токенов временной метки, перемежающихся с видеокадрами. Модель видит “<timestamp 00:32> frame, prompt” и может рассуждать о временных отношениях.

Проблема выравнивания

12% пар изображение—текст в собранном из веба наборе данных содержат описания, не полностью привязанные к изображению. VLM, обученная на таких данных, незаметно учится галлюцинировать: выдумывать объекты, неверно читать числа, изобретать связи. В промышленной среде это доминирующий режим отказа.

Skywork.ai предложила Cross-Modal Error Rate (CMER) для его отслеживания:

CMER = fraction of outputs where the text confidence is high but the image-text similarity (via a CLIP-family checker) is low

Высокий CMER означает, что модель уверенно сообщает вещи, не обоснованные изображением. Мониторинг CMER и использование его как производственного KPI сократили частоту галлюцинаций примерно на 35% в их развёртывании. Хитрость не в том, чтобы «исправить модель», а в том, чтобы «направлять ответы с высоким CMER на проверку человеком».

Дообучение с LoRA / QLoRA

Полное дообучение VLM на 70B недоступно большинству команд. LoRA (ранг 16–64) на слоях внимания и проектора либо QLoRA с базовыми весами в 4 битах помещается на одном A100 / H100. Стоимость: 5 000–50 000 примеров, $100–$5 000 вычислений, 2–10 часов обучения.

Пространственное рассуждение всё ещё слабо

Текущие VLM получают 50–60% на бенчмарках пространственного рассуждения (выше—ниже, слева—справа, подсчёт, расстояние). Если ваш сценарий зависит от вопроса «какой объект расположен над каким», тщательно валидируйте результат: общая производительность VLM ниже человеческой. Альтернативы, превосходящие VLM в чисто пространственных задачах: специализированный оценщик ключевых точек / позы, модель глубины либо модель обнаружения с последующей обработкой геометрии рамок.

Соберите это

Шаг 1: Проектор

Именно эту часть вам чаще всего предстоит обучать. MLP из 2–4 слоёв с GELU.

import torch
import torch.nn as nn


class Projector(nn.Module):
    def __init__(self, vit_dim=768, llm_dim=4096, hidden=4096):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(vit_dim, hidden),
            nn.GELU(),
            nn.Linear(hidden, llm_dim),
        )

    def forward(self, x):
        return self.net(x)

На вход подаётся тензор токенов (N_patches, d_vit). На выходе получается (N_patches, d_llm). LLM воспринимает каждую строку выхода как ещё один токен.

Шаг 2: Соберите ViT-MLP-LLM от начала до конца

Каркас прямого прохода для минимальной VLM. Реальный код использует transformers; здесь показана концептуальная компоновка.

class MinimalVLM(nn.Module):
    def __init__(self, vit, projector, llm, image_token_id):
        super().__init__()
        self.vit = vit
        self.projector = projector
        self.llm = llm
        self.image_token_id = image_token_id  # placeholder token in text prompt

    def forward(self, image, input_ids, attention_mask):
        # 1. vision features
        vision_tokens = self.vit(image)                     # (B, N_patches, d_vit)
        vision_embeds = self.projector(vision_tokens)       # (B, N_patches, d_llm)

        # 2. text embeddings
        text_embeds = self.llm.get_input_embeddings()(input_ids)  # (B, M, d_llm)

        # 3. replace image placeholder tokens with vision embeds
        merged = self._merge(text_embeds, vision_embeds, input_ids)

        # 4. run LLM
        return self.llm(inputs_embeds=merged, attention_mask=attention_mask)

    def _merge(self, text_embeds, vision_embeds, input_ids):
        out = text_embeds.clone()
        expected = vision_embeds.size(1)
        for b in range(input_ids.size(0)):
            positions = (input_ids[b] == self.image_token_id).nonzero(as_tuple=True)[0]
            if len(positions) != expected:
                raise ValueError(
                    f"batch item {b} has {len(positions)} image tokens but vision_embeds has {expected} patches."
                    " Every sample in the batch must be pre-padded to the same number of image placeholder tokens.")
            out[b, positions] = vision_embeds[b]
        return out

Токен-заполнитель <image> в тексте заменяется настоящими эмбеддингами изображения — тот же паттерн используют LLaVA, Qwen-VL и InternVL.

Шаг 3: Вычисление CMER

Лёгкая проверка во время выполнения.

import torch.nn.functional as F


def cross_modal_error_rate(image_emb, text_emb, text_confidence, sim_threshold=0.25, conf_threshold=0.8):
    """
    image_emb, text_emb: embeddings of image and generated text (normalised internally)
    text_confidence:     mean per-token probability in [0, 1]
    Returns:             fraction of high-confidence outputs with low image-text alignment
    """
    image_emb = F.normalize(image_emb, dim=-1)
    text_emb = F.normalize(text_emb, dim=-1)
    sim = (image_emb * text_emb).sum(dim=-1)        # cosine similarity
    high_conf_low_sim = (text_confidence > conf_threshold) & (sim < sim_threshold)
    return high_conf_low_sim.float().mean().item()

Относитесь к CMER как к производственному KPI. Отслеживайте его по конечной точке, типу запроса и клиенту. Рост CMER показывает, что модель начинает галлюцинировать на некотором распределении входных данных.

Шаг 4: Игрушечный классификатор VLM (запускаемый)

Покажите, что проектор обучается. На вход поступают искусственные «признаки ViT»; крошечный токен в стиле LLM предсказывает класс.

class ToyVLM(nn.Module):
    def __init__(self, vit_dim=32, llm_dim=64, num_classes=5):
        super().__init__()
        self.projector = Projector(vit_dim, llm_dim, hidden=64)
        self.head = nn.Linear(llm_dim, num_classes)

    def forward(self, vision_tokens):
        projected = self.projector(vision_tokens)
        pooled = projected.mean(dim=1)
        return self.head(pooled)

Эту модель можно подогнать на синтетических парах (признак, класс) менее чем за 200 шагов — этого достаточно, чтобы показать работоспособность паттерна проектора.

Используйте это

В 2026 году производственные команды используют VLM тремя способами:

  • Размещённый API — OpenAI Vision, Anthropic Claude Vision, Google Gemini Vision. Нулевая инфраструктура, риск зависимости от поставщика.
  • Самостоятельное развёртывание open source — Qwen3-VL или InternVL3.5 через transformers и vllm. Полный контроль, больше начальных усилий.
  • Дообучение на домене — загрузите Qwen2.5-VL-7B или LLaVA-1.6-7B, примените LoRA к 5k–50k пользовательским примерам, обслуживайте через vllm или TGI.
from transformers import AutoProcessor, AutoModelForVision2Seq
import torch
from PIL import Image

model_id = "Qwen/Qwen3-VL-8B-Instruct"
processor = AutoProcessor.from_pretrained(model_id)
model = AutoModelForVision2Seq.from_pretrained(model_id, torch_dtype=torch.bfloat16, device_map="auto")

messages = [{
    "role": "user",
    "content": [
        {"type": "image", "image": Image.open("plot.png")},
        {"type": "text", "text": "What does this chart show?"},
    ],
}]
inputs = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt").to("cuda")
generated = model.generate(**inputs, max_new_tokens=256)
answer = processor.decode(generated[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)

apply_chat_template скрывает токенизацию заполнителя <image>; модель выполняет объединение сама.

Внедрите это

Этот урок создаёт:

  • outputs/prompt-vlm-selector.md — выбирает Qwen3-VL / InternVL3.5 / LLaVA-Next / API с учётом точности, задержки, длины контекста и бюджета.
  • outputs/skill-cmer-monitor.md — генерирует код для инструментирования промышленной конечной точки VLM с частотой кросс-модальных ошибок, дашбордами по конечным точкам и порогами оповещений.

Упражнения

  1. (Легко) Выполните три запроса («что это?», «посчитай объекты», «опиши сцену») через любую открытую VLM на пяти изображениях. Вручную оцените каждый ответ как правильный / частично правильный / галлюцинированный. Рассчитайте начальную величину, похожую на CMER.
  2. (Средне) Дообучите Qwen2.5-VL-3B или LLaVA-1.6-7B с LoRA (ранг 16) на 500 изображениях целевого домена с подписями. Сравните точность в стиле MMBench без обучения на примерах и после дообучения.
  3. (Сложно) Замените кодировщик изображений VLM на DINOv3 вместо стандартного SigLIP/CLIP. Переобучите только проектор (замороженные LLM и DINOv3). Измерьте, улучшаются ли задачи плотного предсказания (подсчёт, пространственное рассуждение).

Ключевые термины

Термин Как обычно говорят Что это на самом деле означает
ViT-MLP-LLM «Паттерн VLM» Визуальный кодировщик + проектор + языковая модель; основа каждой VLM 2026 года
Проектор «Мост» MLP из 2–4 слоёв (или Q-former), отображающий визуальные токены в пространство эмбеддингов LLM
DeepStack «Трюк с признаками Qwen3-VL» Признаки ViT нескольких уровней складываются вместо использования только последнего слоя
Токен изображения «Заполнитель <image>» Специальный токен в текстовом потоке, заменяемый спроецированными визуальными эмбеддингами
CMER «KPI галлюцинаций» Cross-Modal Error Rate; высок, когда уверенность текста высока, а сходство изображения и текста низко
Визуальный агент «VLM, которая щёлкает» VLM, управляющая GUI (OSWorld, мобильным или веб-интерфейсом) посредством вызовов инструментов
Q-former «Мост с фиксированным числом токенов» Проектор в стиле BLIP-2, создающий фиксированное число визуальных токенов запросов
Выравнивание / предобучение / настройка на инструкции «Три этапа» Стандартный конвейер обучения VLM

Дополнительные материалы


Источник: Vision-Language Models — The ViT-MLP-LLM Pattern 04.24 — SAM 3 и сегментация с открытым словарём · Фаза 04 — Компьютерное зрение · 04.26 — Монокулярная оценка глубины · Полный каталог