AIREITER

Локальный запуск AstaBrief 8B через vLLM для приватного RAG

Последнее обновление: 2026-10-02 19:11:52

AstaBrief 8B не ищет документы сам по себе. Его задача — превратить исследовательский вопрос и переданные научные фрагменты в отчёт с цитатами. Именно это ограничение определяет архитектуру приватного развёртывания: генератор работает за межсетевым экраном, разбор документов и поиск остаются локальными, а модели передаются только отранжированные фрагменты со стабильными ID источников.

Что на самом деле требуется AstaBrief 8B

AstaBrief 8B — текстовая модель на 8 миллиардов параметров от Ai2, созданная на базе Qwen3-8B и выпущенная под лицензией Apache 2.0. В официальной карточке модели входом указаны исследовательский вопрос и найденные фрагменты научной литературы, а не вопрос, который модель должна самостоятельно отправиться искать. Там же отдельно предупреждается: изменение дообученного промпта или формата взаимодействия может привести к ухудшению и нестабильности результатов.

В этом руководстве используйте финальный чекпойнт allenai/AstaBrief_8B. В примере из карточки модели указан allenai/AstaBrief_8B_SFT — это предшествующая версия, полученная на этапе supervised fine-tuning. Несовпадение названий стоит проверить по конкретному скачиваемому чекпойнту, а не молча считать две модели взаимозаменяемыми.

Публичный репозиторий Ai2 ScholarQA полезен как пример эталонной архитектуры: поиск, необязательное переранжирование, агрегация на уровне статей, извлечение цитат и генерация отчёта там разделены на отдельные компоненты. В приватной системе лучше сохранить это разделение, даже если вместо Semantic Scholar используется внутренний индекс.

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

В приватном пайплайне должны быть явно выделены шесть этапов:

  1. Загрузка и разбор: извлекайте текст из PDF, распознавайте отсканированные страницы и сохраняйте ID документа, название, страницу, раздел и диапазоны символов.
  2. Разбиение на фрагменты: делите текст на фрагменты умеренного размера, не теряя границы страниц и заголовки.
  3. Поиск: сочетайте лексический поиск с эмбеддингами, если важны терминология, идентификаторы или точные фразы.
  4. Переранжирование: оценивайте кандидатов первого этапа с учётом полного вопроса и оставляйте небольшой набор доказательств.
  5. Сборка: назначайте неизменяемые ID цитат и форматируйте фрагменты в ожидаемой AstaBrief структуре ссылок.
  6. Генерация: отправляйте собранный промпт на локальный endpoint vLLM.

Ключевое архитектурное решение — не выбор конкретной векторной базы. Важнее контракт доказательств: каждый передаваемый модели фрагмент должен иметь стабильный ID, по которому приложение сможет найти исходный документ и страницу.

Делайте ID цитат стабильными

Используйте ID вроде DOC_014_P07_A, а не позиции в массиве. Позиции меняются при настройке поиска, тогда как ID документа, страницы и фрагмента остаётся пригодным для аудита.

Храните соответствие ID и метаданных отдельно от промпта:

{
  "DOC_014_P07_A": {
    "document": "internal_protocol.pdf",
    "page": 7,
    "section": "Methods",
    "char_start": 18420,
    "char_end": 19210
  }
}

В промпте показывайте тот же ID рядом с фрагментом. После генерации отклоняйте или помечайте цитаты, которых нет в переданном наборе ID. Это не доказывает, что процитированный фрагмент подтверждает каждое утверждение, но устраняет самый простой вид выдуманных ссылок.

Заранее определите объём поиска и контекста

Не отправляйте в контекст все совпавшие фрагменты. Сначала ищите с запасом по полноте, затем выполняйте переранжирование и упаковывайте только те passages, которые укладываются в бюджет промпта и напрямую помогают ответить на вопрос. Соседние фрагменты с одной страницы можно объединять, если это сохраняет целостность рассуждения, но при необходимости постраничной трассировки в финальном отчёте оставляйте отдельные ID.

В репозитории Ai2 ScholarQA описана эталонная конфигурация, которая находит 256 кандидатов, переранжирует их и оставляет 50 результатов на уровне статей. Эти значения относятся к публичному пайплайну, а не являются универсальным требованием AstaBrief. Для небольших приватных коллекций начните с меньших значений, анализируйте пропущенные доказательства и подбирайте параметры поиска и контекста под собственные вопросы.

Запустите AstaBrief 8B через vLLM

В официальных материалах нет единого требования к объёму VRAM для всех сочетаний dtype, длины контекста и уровня параллелизма. Начните с неквантизированного чекпойнта на оборудовании, способном его загрузить. Если ресурсов не хватает, сначала уменьшите параллелизм или длину контекста, а уже затем проверяйте квантизированную сборку. Не предполагайте, что квантизация сохранит качество цитирования без тестирования на вашем корпусе.

Установите vLLM в чистое окружение, совместимое с вашим стеком CUDA и PyTorch. Затем запустите OpenAI-совместимый сервер с финальным чекпойнтом:

pip install -U vllm openai

vllm serve allenai/AstaBrief_8B \
  --host 127.0.0.1 \
  --port 8000 \
  --dtype auto \
  --max-model-len 16000

Параметр --max-model-len задаёт операционный потолок, а не означает, что каждый запрос должен содержать 16 000 токенов. В карточке модели указана максимальная длина обучения 16 000 токенов, тогда как в примере для генерации используется max_tokens=4096.

Проверьте локальный endpoint

curl http://127.0.0.1:8000/v1/models

Затем отправьте запрос в том же формате промпта, который использовался в данных для дообучения. В официальном примере заданы temperature 0.7, top-p 0.95, максимум 4 096 генерируемых токенов и EOS-токен токенизатора как условие остановки.

from openai import OpenAI

client = OpenAI(
    base_url="http://127.0.0.1:8000/v1",
    api_key="local-only",
)

response = client.chat.completions.create(
    model="allenai/AstaBrief_8B",
    temperature=0.7,
    top_p=0.95,
    max_tokens=4096,
    messages=[
        {"role": "user", "content": assembled_prompt},
    ],
)

print(response.choices[0].message.content)

В приватной инфраструктуре привяжите сервер к loopback-интерфейсу или внутреннему адресу, вынесите аутентификацию и TLS на шлюз и запретите внешний входящий трафик. Локальная модель сама по себе не делает приватными логи, временные PDF-файлы и данные трассировки.

Соберите приватный запрос с поиском

Следующий каркас намеренно не привязан к конкретной реализации индекса. Критичны три вещи: список отранжированных доказательств, неизменяемые ID и чёткая граница промпта.

from dataclasses import dataclass
from openai import OpenAI

@dataclass
class Evidence:
    ref_id: str
    text: str
    title: str
    page: int


def build_prompt(question: str, evidence: list[Evidence]) -> str:
    references = "\n\n".join(
        f"[{item.ref_id}] {item.title} (page {item.page})\n{item.text}"
        for item in evidence
    )
    return f"""Research question:
{question}

Retrieved references:
{references}

Write a cited research report answering the question. Use only the supplied
references for factual support. Attach the supplied reference IDs to claims.
If the references do not establish a point, say that the evidence is
insufficient instead of inventing a source.
"""


def answer(question: str, evidence: list[Evidence]) -> str:
    client = OpenAI(base_url="http://127.0.0.1:8000/v1", api_key="local-only")
    prompt = build_prompt(question, evidence)
    result = client.chat.completions.create(
        model="allenai/AstaBrief_8B",
        temperature=0.7,
        top_p=0.95,
        max_tokens=4096,
        messages=[{"role": "user", "content": prompt}],
    )
    return result.choices[0].message.content

В production используйте официальный шаблон промпта AstaBrief и подставляйте найденные фрагменты, сохраняя их ID ссылок. Сокращённая инструкция выше показывает интеграцию с vLLM, но не заменяет формат, использованный при дообучении.

Приватный индекс может работать на BM25, плотном поиске или их комбинации. Передавайте метаданные без потерь через все этапы. Фрагмента без ID документа и номера страницы недостаточно для обоснованного исследовательского отчёта, даже если сгенерированный текст звучит убедительно.

Добавьте проверку цитат и приватности до выхода в production

Заявленные для AstaBrief результаты ScholarQA-CS2 полезны как ориентир, но не гарантируют такого же качества на вашем корпусе. На тестовом наборе из 100 вопросов в карточке модели AstaBrief 8B показывает точность цитирования 90.5 и полноту цитирования 78.2; точность ответа составляет 89.0. Более низкая полнота цитирования по сравнению с точностью — важный практический сигнал: отчёт может корректно ссылаться на переданные материалы и при этом пропускать существенные доказательства.

Перед выпуском добавьте четыре проверки:

  1. Корректность ссылок: каждый сгенерированный ID цитаты должен присутствовать в списке разрешённых ID запроса.
  2. Разрешение метаданных: каждый ID должен вести к документу, странице и сохранённому фрагменту текста.
  3. Поддержка утверждений: рецензент или отдельный валидатор должен проверить, действительно ли фрагмент подтверждает близлежащее утверждение.
  4. Полнота поиска: поддерживайте небольшой размеченный набор вопросов с ожидаемыми документами и страницами, а затем измеряйте пропуски после изменений в разбиении, эмбеддингах или переранжировании.

Держите сервер модели, индекс, объектное хранилище, логи и мониторинг в одной доверенной зоне, если только ваша политика явно не допускает внешний сервис. Отключите логирование тела запросов для чувствительных документов, по возможности удаляйте запросы из трассировок и задайте сроки хранения загруженных PDF и сгенерированных отчётов.

Не используйте заявленное Ai2 значение 51.1 секунды в Fast-mode как локальный бенчмарк. Это показатель полного пайплайна Asta, а в self-hosted-развёртывании меняются GPU, система поиска, батчинг, длина промпта и сетевой маршрут. Измеряйте отдельно время поиска, переранжирования, ожидания первого токена, генерации и полного запроса.

Ищите проблемы по уровням пайплайна

СимптомВероятный уровеньЧто проверить сначала
Сервер запускается, но цитаты в ответе плохого качестваПромпт или контракт доказательствСравнить промпт с официальным форматом и проверить стабильность ID ссылок
Цитаты никуда не ведутВалидация приложенияОтклонять ID, которых нет в списке разрешённых для запроса
Релевантные статьи не находятсяПоискПроверить разбиение, гибридный поиск и полноту переранжировщика, прежде чем менять модель
Запросы завершаются из-за нехватки памятиСервинг или упаковка контекстаУменьшить число параллельных запросов, бюджет вывода или объём контекста; затем вернуться к вопросу квантизации
Локальная задержка неожиданно высокаяВесь пайплайнОтдельно измерить поиск, переранжирование, постановку в очередь и генерацию
Приватные данные появляются в логахЭксплуатацияПроверить настройки хранения шлюза, vLLM, трассировок, кэша и объектного хранилища

Диагностика по уровням помогает не принять пропуск на этапе поиска за проблему модели и не пытаться «лечить» несовпадение формата промпта добавлением новых документов.

Используйте AstaBrief 8B, если вам нужен специализированный локальный генератор отчётов и вы готовы самостоятельно отвечать за качество поиска, сопоставление источников и валидацию. vLLM решает задачу сервинга модели, но не предоставляет поиск по документам, происхождение цитат и средства контроля приватности.

Источники