Подготовка ONNX-моделей для семантического поиска

Доступно только в PRO версии! Требует включенных эмбеддингов в секции [pro.search], подготовленной ONNX-модели и загруженного ONNX Runtime.
CPU-рантайм уже в архиве PRO. Если нужен GPU (CUDA/DirectML) или вы настраиваете рантайм вручную, см. раздел ONNX Runtime в PRO.

Семантический поиск (эмбеддинги) требует предварительно подготовленную ONNX-модель. Сервис поддерживает модели семейства E5 (e5-small, e5-base, e5-large) и BGE-M3. CLI-утилита может автоматически скачать, экспортировать и квантовать модель.

Что такое квантование? Это процесс уменьшения размера модели. FP32 → INT8 уменьшает размер в 4 раза (с 440 MB до 110 MB) с минимальной потерей точности (1-3%). Рекомендуется для production на CPU.

Быстрый старт: подготовка E5-small модели

# 1. Установка зависимостей (один раз)
    pip install optimum[onnxruntime] transformers torch onnx huggingface-hub --break-system-packages
    
    # 2. Подготовка модели (скачать, экспортировать, квантовать в INT8)
    # CLI-утилита sku-cli (входит в поставку) поддерживает команду model prepare.
    sku-cli model prepare \
        --model intfloat/e5-small-v2 \
        --output ./models/e5 \
        --quantize int8 \
        --optimize
    
    # 3. Проверка, что модель готова
    ls -la ./models/e5/int8/
    # Должны быть: model.onnx, tokenizer.json, config.json
    
    # 4. Настройка config.toml:
    # model_path = "./models/e5/int8/model.onnx"
    # vector_dimension = 384

Доступные модели

МодельРазмер (INT8)РазмерностьСкоростьТочностьДля каких задач
intfloat/e5-small-v2~120 MB384очень быстросреднеОбщие задачи, быстрый поиск
intfloat/e5-base-v2~440 MB768средневысокаяТочный поиск, сложные запросы
intfloat/e5-large-v2~1.3 GB1024медленномакс. точностьНаучные тексты, медицинские базы
BAAI/bge-m3~650 MB1024среднемакс. точностьМультиязычный поиск, редкие слова

Подготовка BGE-M3 (особый случай)

BGE-M3 — большая модель (1.1B параметров). Прямая конвертация через optimum-cli может занять часы и потребовать 32+ GB RAM. Рекомендуется скачать готовую ONNX-модель.
# Скачать INT8 модель (рекомендуется)
    huggingface-cli download skatzR/USER-BGE-M3-ONNX-INT8 --local-dir ./models/bge-m3/int8
    
    # Или FP16 модель
    huggingface-cli download hotchpotch/vespa-onnx-BAAI-bge-m3-only-dense --local-dir ./models/bge-m3/fp16
    
    # Настройка config.toml:
    # [pro.search.embedding]
    # active_backend = "bge_m3"
    # vector_db_path = "./data/vectors.lance"
    # query_cache_enabled = true
    # session_pool_size задается только в секции бэкенда (.bge_m3 / .e5)
    #
    # [pro.search.embedding.bge_m3]
    # enabled = true
    # model_path = "./models/bge-m3/int8/model.onnx"
    # vector_dimension = 1024
    # enable_sparse = false
    # pooling = "mean"
    # intra_op_threads = 4
    # inter_op_threads = 1
    # session_pool_size = 1

Параметры команды model prepare

\--model обязательный
Идентификатор модели на Hugging Face. Например: `intfloat/e5-small-v2`, `BAAI/bge-m3`.
\--output обязательный
Папка для сохранения модели. Внутри будут созданы подпапки: `onnx/` (FP32), `int8/` или `fp16/`.
\--quantize none \| int8 \| fp16 none
Тип квантования.
  • none — сохранить FP32 (оригинальный размер, максимальная точность)
  • int8 — 8-битное целочисленное (рекомендуется для CPU, размер в 4 раза меньше)
  • fp16 — 16-битное с плавающей точкой (баланс, размер в 2 раза меньше)
\--optimize флаг
Применить оптимизацию O2 при экспорте (ускорение инференса на 20-30%).
\--task строка "feature-extraction"
Задача ONNX-экспорта. Для embedding-моделей используется `feature-extraction`.

Проверка модели

После подготовки модели рекомендуется проверить, что она корректно загружается:

# Запускаем сервис
    ./sku-service --config config.toml
    
    # В другом терминале проверяем статус эмбеддингов
    curl http://localhost:8080/health | jq .embedding
    
    # Ожидаемый ответ:
    # {
    #   "enabled": true,
    #   "model_loaded": true,
    #   "vector_count": 50000,
    #   "vector_dimension": 384,
    #   "avg_search_time_ms": 12.3
    # }
# Тот же запрос через CLI
sku-cli health
Частые проблемы и их решение:
  • Embedding включен, но /health показывает embedding.loaded = false — проверьте, что папка runtime/ с нужным рантаймом лежит рядом с sku-service. Подробности в разделе ONNX Runtime в PRO.
  • "No module named 'optimum'" — установите зависимости: pip install optimum[onnxruntime] transformers torch onnx huggingface-hub
  • "File too large" / protobuf limit — используйте use_external_data_format=True (скрипт делает это автоматически)
  • Модель не загружается в сервис — проверьте путь в config.toml. Должен быть абсолютный или относительно корня проекта.
  • Медленный инференс — включите квантование (--quantize int8) и настройте intra_op_threads = 4 в конфиге.
  • Out of memory — уменьшите batch_size в конфиге (например, с 64 до 32).
Рекомендации по выбору модели:
  • Для большинства задач — intfloat/e5-small-v2 + INT8 квантование. Баланс скорости и качества.
  • Для высокой точности — intfloat/e5-base-v2 + INT8. Требует больше RAM, но точнее.
  • Для мультиязычного поиска (русский, английский, немецкий) — BAAI/bge-m3 (готовая INT8 модель с Hugging Face).
  • Для слабых серверов (2-4 GB RAM) — только полнотекстовый поиск, эмбеддинги отключить.

Пример полной настройки config.toml для E5-small

[pro]
    enabled = true
    
    [pro.search.orchestrator]
    fs_enabled = true
    embedding_enabled = true
    strategy = "hybrid"
    tantivy_weight = 0.6
    embedding_weight = 0.4
    
    [pro.search.embedding]
    active_backend = "bge_m3"  # или "e5"
    vector_db_path = "./data/vectors.lance"
    query_cache_enabled = true
    # session_pool_size задается только в секции бэкенда (.bge_m3 / .e5)
    
    [pro.search.embedding.bge_m3]
    enabled = true
    model_path = "./models/bge-m3-int8/model.onnx"
    vector_dimension = 1024
    enable_sparse = false
    pooling = "mean"
    intra_op_threads = 4
    inter_op_threads = 1
    session_pool_size = 1

    # Для E5-small раскомментируйте и выключите bge_m3 выше:
    # [pro.search.embedding.e5]
    # enabled = true
    # model_path = "./models/e5-small-int8/model.onnx"
    # model_type = "e5-small"
    # vector_dimension = 384
    # pooling = "mean"
    # intra_op_threads = 4
    # inter_op_threads = 1
    # session_pool_size = 1