LINUX.ORG.RU

Развёртывание и базовая настройка LibreChat

 librechat, litellm, , ,


2

3

Нельзя не заметить, что небольшое, но очень дружное сообщество LORa феноменально мало пишет о достижениях и возможностях «народного хозяйства» с очень плодородных полей открытых LLM (large language model), и всего опенсорсного с этим связанного. Сегодня я расскажу вам о LibreChat.

Что такое LibreChat

LibreChat – это платформа с открытым исходным кодом, во многом копирующая интерфейс ChatGPT, и взаимодействующая с различными LLM (как открытими локальными, так и большими коммерческими, через api). По сути, это клиентское приложение, которое позволяет общаться с LLM, предоставляя при этом множество дополнительных функций.

Ключевые возможности LibreChat:

  1. Поддержка множества ИИ-моделей: LibreChat позволяет подключаться и использовать модели от разных поставщиков, включая OpenAI, Azure, Bing AI, Google, Anthropic, DeepSeek, а также локально запущенные модели через Ollama и LM Studio.
  2. Расширенные возможности управления диалогами: LibreChat предлагает инструменты для редактирования сообщений, повторной отправки запросов, поиска по истории сообщений, создания «веток» (forking) диалогов для исследования разных путей ответа, а также импорта и экспорта бесед.
  3. Настройка и Пресеты: Пользователи могут создавать и сохранять пользовательские «пресеты» (presets) — предопределенные конфигурации для разных моделей ИИ. Это позволяет быстро переключаться между настроенными профилями, например, с разными системными сообщениями, параметрами температуры или моделями.
  4. Поддержка Плагинов: LibreChat интегрирует поддержку плагинов, например таких как плагины для поиска в интернете и генерации изображений с помощью Stable Diffusion.
  5. Многопользовательский Режим: Существует возможность настройки LibreChat для использования несколькими пользователями с аутентификацией и управлением учетными записями.
  6. Интерфейс и Удобство: Цель проекта — предоставить улучшенный, интуитивно понятный и настраиваемый интерфейс для работы с ИИ, включая такие детали, как отображение количества токенов и потенциальной стоимости запросов.

Иными словами, основное назначение LibreChat – предоставить централизованную и гибкую платформу для взаимодействия с различными технологиями искусственного интеллекта.

В этой статья я покажу, как развернуть LibreChat на локальной машине, через docker-compose, как его просто настроить в связке с коммерческими LLM, как его настроить для работы с Reverse proxy и как его настроить в связке с локальными LLM.


Локальное развёртывание LibreChat

Локальное развёртывание через docker-compose я выбрал неслучайно, оно ничем не проще облачного, зато так вы сможете посмотреть на что способен LibreChat, если вы будете запускать его вместе с очень полезными локальными инструментами, на запуск которых простой сервер не способен. При этом настройки локального и облачного развёртывания отличаются не сильно, но всё же позже я вскользь упомяну разницу между ними. Если вас не устраивает docker compose, то LibreChat даёт возможность развернуть локально с помощью npm или в облаке, через Hugging Face или Railway.

Установка LibreChat

Раз уж я выбрал docker-compose, то предполагается, что он уже у вас установлен вместе с docker/podman, под podman желательно внести изменения в конфиг docker-compose.override.yml и поменять многие bind mounts на named volumes.

$ git clone https://github.com/danny-avila/LibreChat.git
$ cd LibreChat
$ cp .env.example .env
$ docker-compose up -d
or
$ podman compose up -d

Для обновления контейнера:

$ docker-compose down
$ git pull
$ docker-compose pull
$ docker compose up -d

Если podman, то аналогично:

$ podman compose down
$ git pull
$ podman compose pull
$ podman compose up -d

Здесь одно из основных отличий с облачным развёртыванием. В облаке вместо docker-compose.yml, нужно запускать deploy-compose.yml, а обновление будет происходить по скрипту npm run update:deployed. Второе различие связано с тем, что скорее всего на сервере вы будете запускать docker/podman от рута. Локально же перед вами открывается необходимость запускать контейнеры в rootless режиме. По моему мнению podman подходит для этого намного лучше, но эта тема не этой статьи.

Чтобы посмотреть список запущенных контейнеров и их логи:

$ docker ps
$ docker logs ваш контейнер

podman:

$ podman ps
$ podman logs ваш контейнер

Теперь идёте на http://localhost:3080/ и видите экран входа. Регистрируйтесь: придумайте себе логин, пароль, напишите какую-то почту. Регистрация просто наследуется из облачной версии, а первым по умолчанию создается учётная запись админа. Можете входить в учётную запись, первичная установка закончена, но в таком виде LibreChat бесполезен. Самое время настроить доступ к LLM.

Настройка LibreChat

Теперь важное замечание. Ваш LibreChat работает, вы можете любоваться его ChatGPT-подобным интерфейсом, но во всём этом нет толка, если вы не обладаете ключами от коммерческих моделей или не имеете достаточно мощного компьютера, чтобы развернуть на нём свои родные локальные.

Часть первая: бесхитростная

Если вы обладаете коммерческими ключами от LLM, а ваша локальная машина постоянно находится не в России или делает вид, что там не находится, то подключенине к LLM будет очень скучным. Если это не так, и ваши ключи не от DeepSeek, то переходите сразу ко второй части. Дело в том, что большинство провайдеров коммерческих моделей определяют страну из которой сделан запрос и блокируют его, если эта страна их не устраивает. DeepSeek исключение, он предоставляет доступ в Россию напрямую.

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

Если этот путь не для вас, то открывайте .env, раскомментируйте эти строки и записывайте все свои ключи:

DEEPSEEK_API_KEY="ВАШ КЛЮЧ"
ANTHROPIC_API_KEY="ВАШ КЛЮЧ"
MISTRAL_API_KEY="ВАШ КЛЮЧ"
OPENROUTER_KEY="ВАШ КЛЮЧ"
GOOGLE_KEY="ВАШ КЛЮЧ"
OPENAI_API_KEY="ВАШ КЛЮЧ"
Итд

Дополнительно в .env можете указать конкретные модели, с которыми хотите иметь дело:

OPENAI_MODELS="Список LLM"
GOOGLE_MODELS="Список LLM"
Итд

В завершении вносите туда адрес RAG (об этом подробнее чуть позже):

RAG_PORT=8000
RAG_API_URL=http://host.docker.internal:8000

Если у вас есть api от OpenAI, то на этом всё, а если у вас api от других LLM, то дополнительно вносите:

EMBEDDINGS_PROVIDER="google" # ИЛИ КТО УГОДНО ПОПУЛЯРНЫЙ

Это будет работать, если у вас кто-то популярный типо google, а так же ранее был внесён ключ в соответствующую секцию, в вашем случае в GOOGLE_KEY

Работая с файлом .env, не забывайте проверить, что он добавлен в ваш .gitignore, если вы, конечно, не коммунист!

Перезагружайте docker-compose, настройка завершена.

Часть вторая: с хитрицой

Если вы обладаете коммерческими ключами от LLM, а ваша локальная машина постоянно находится в России и не делает вид, что там не находится, и ваши ключи не от DeepSeek, то подключенине к LLM будет менее скучным. Для этого вам понадобится vps другой страны.

Собственно тогда вы можете и LibreChat развернуть прямо на сервере, вскользь я упоминал, что нужно делать. Но в этом случае вам будет неудобно взаимодействовать с локальными LLM и не только. Чтобы вы могли достучаться до большинства коммерческих LLM, вам придётся настроить Reverse proxy, в вашем случае это будут (именно будУТ) nginx и LiteLLM.


Что такое LiteLLM

С nginx понятно зачем он нужен, но что такое LiteLLM? LiteLLM — это Python-библиотека, которая предоставляет единый, стандартизированный способ отправки запросов к api множества различных LLM провайдеров, в том числе и локальных. Вместо того чтобы изучать и реализовывать специфические детали api каждого провайдера, вы можете использовать единый вызов функции LiteLLM.

Основные возможности LiteLLM:

  1. Унификация api: Это главная задача. У разных провайдеров разные названия параметров, форматы запросов и ответов, методы аутентификации. LiteLLM скрывает эту сложность за единым интерфейсом (обычно это функция litellm.completion() или litellm.acompletion() для асинхронных вызовов). Вы просто указываете, какую модель использовать, а LiteLLM сам формирует правильный запрос к нужному api.

  2. Простота переключения между моделями/провайдерами: Благодаря единому интерфейсу, переход с одной модели на другую (даже от другого провайдера) часто требует изменения всего одной строки кода — имени модели.

  3. Поддержка множества LLM: LiteLLM поддерживает десятки api всех популярных LLM провайдеров. А локальные LLM используют те же api, что и коммерческие.

  4. Функциональность прокси-сервера: это очень важная для вас вещь. LiteLLM можно запустить как отдельный прокси-сервер. В этом режиме он принимает запросы в стандартном формате (часто совместимом с OpenAI api) и перенаправляет их к настроенным LLM провайдерам. Это дает дополнительные возможности:

    • Обход блокировок по geoip: Запрос к LLM провайдеру будет отправелн с вашего иностранного сервера.
    • Централизованное управление ключами api: Не нужно хранить ключи в каждом приложении.
    • Балансировка нагрузки: Распределение запросов между несколькими экземплярами моделей или провайдерами.
    • Резервные модели (Fallbacks): Автоматическое переключение на другую модель, если основная недоступна или выдает ошибку.
    • Кэширование: Сохранение ответов на одинаковые запросы для экономии средств и ускорения.
    • Ограничение частоты запросов (Rate Limiting): Контроль нагрузки на api.
    • Отслеживание затрат: Централизованный учет стоимости вызовов разных моделей.
    • Логирование и мониторинг: Единое место для сбора логов и метрик использования LLM.

1. Настройка nginx

Теоретически, чтобы реализовать работу Reverse proxy для запросов к api LLM, можно обойтись только одним nginx. Но тогда непременно придётся городить велосипеды в попытках обратиться к разным LLM, поэтому вам и нужна связка из nginx и LiteLLM.

Предполагается, что вы знаете, как настривать nginx и можете адаптировать свой конфиг под работу вместе с LiteLLM. Если нет, то вкратце: ваш сервер должен быть доступен по https, в самом простом случае для этого вы должны установить nginx и certbot. Ввести эту команду certbot --nginx -d ВАШ DNS или IP.

Пример простейщего конфига /etc/nginx/sites-available/librechat-proxy:

# /etc/nginx/sites-available/librechat-proxy

server {
    listen 80;
    server_name ВАШ DNS или IP;

    # Letsencrypt challenge handling (если используете certbot --nginx)
    location ~ /.well-known/acme-challenge/ {
        allow all;
        root /var/www/html; # Укажите путь, используемый Certbot
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl http2;
    server_name ВАШ DNS или IP;

    ssl_certificate /etc/letsencrypt/live/ВАШ DNS или IP/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ВАШ DNS или IP/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    # Дополнительные заголовки безопасности (опционально)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options SAMEORIGIN always;
    # add_header Content-Security-Policy "default-src 'self'"; # Будьте осторожны с CSP

    location / {
        # Проксируем на LiteLLM, который слушает на порту 4000 на localhost хоста
        proxy_pass http://127.0.0.1:4000;

        # Стандартные заголовки для проксирования
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Настройки для поддержки потоковой передачи (важно для LLM)
        proxy_http_version 1.1;         # Обязательно для keepalive и chunked transfer encoding
        proxy_set_header Connection ""; # Сбрасываем заголовок Connection для апстрима
        proxy_buffering off;            # Отключаем буферизацию ответа от бэкенда
        proxy_cache off;                # Отключаем кеширование Nginx

        # Иногда этот заголовок может помочь с буферизацией в некоторых клиентах/серверах
        proxy_set_header X-Accel-Buffering no;

        # Увеличение таймаутов (важно для долгих запросов LLM)
        proxy_connect_timeout 300s; # Время на установку соединения с LiteLLM
        proxy_send_timeout 300s;    # Время на передачу запроса LiteLLM
        proxy_read_timeout 300s;    # Время на чтение ответа от LiteLLM (самый важный)
        send_timeout 300s;          # Время на передачу ответа клиенту

        # Максимальный размер тела запроса (если нужно передавать большие контексты)
        client_max_body_size 50m; # Установите разумный лимит (50m может быть избыточно)
    }

    # Добавьте location для favicon и статики Nginx, чтобы они не шли в LiteLLM (опционально)
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    # Добавьте обработку ошибок (опционально)
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html; # Или другой путь к стандартным страницам ошибок
    }
}

Проверьте:

nginx -t

Вы должны получить syntax is ok и test is successful. Если это так перезагружайте nginx systemctl restart nginx. Его настройка завершена.

2. Установка LiteLLM

Для установки LiteLLM вам снова понадобится docker-compose и docker/podman:

git clone https://github.com/BerriAI/litellm.git
cd litellm
cp .env.example .env
touch config.yaml

Дежурное напоминание, работая с файлом .env, не забывайте проверить, что он добавлен в ваш .gitignore, если вы, конечно, не коммунист!

3. Настройка docker-compose.override.yml

Внимательно прочтите ваш docker-compose.yml. В нём описана работа трёх контейнеров, работающих вместе: litellm_litellm_1основной сервис LiteLLM Proxy, litellm_db_1база данных PostgreSQL и litellm_prometheus_1система мониторинга Prometheus. В принципе вы можете переписать свой docker-compose.yml так, чтобы работал только первый контейнер, для простейшего обхода ограничений и работы с LLM этого будет достаточно. Другие контейнеры нужны для реализации всего функционала, описанного где-то выше.

После создаёте docker-compose.override.yml в него записываете:

# docker-compose.override.yml
version: "3.11" # Используйте ту же версию, что и в основном файле

services:
  litellm:
    # Подключаете ваш кастомный конфиг внутрь контейнера
    volumes:
      - ./config.yaml:/app/config.yaml:ro # :ro - монтируйте только для чтения

    # Указываете LiteLLM использовать ваш конфиг при запуске
    command:
      - "--config"
      - "/app/config.yaml"
      # Если нужно добавить другие флаги, например, для включения дебага:
      # - "--debug"

    # Убедитесь, что переменные из .env файла загружаются (это уже есть в базовом конфиге, но для ясности можно продублировать)
    env_file:
      - .env

4. Настройка .env

Вам необходимо сгенерировать свой LITELLM_MASTER_KEY. Сделать это можно например, с помощью: openssl rand -base64 32, или как вам будет удобно. Этот ключ нужен для управления LITELLM. Вы создадите с помощью него «фейковые» ключи для LibreChat. Ключ обязательно должен начинаться с sk-.

# Development Configs
LITELLM_MASTER_KEY = "sk-СГЕНЕРИРОВАННЫЙ КЛЮЧ"

# ЭТО НАСТРОЙКИ ИЗ .env.example, ЕСЛИ ВЫ ИСПОЛЬЗУЕТЕ ОРИГИНАЛЬНУЮ СВЯЗКУ ИЗ ТРЁХ КОНТЕНЕРОВ
DATABASE_URL = "postgresql://llmproxy:dbpassword9090@db:5432/litellm"
STORE_MODEL_IN_DB = "True"

# ДАЛЬШЕ БУДУТ КЛЮЧИ ВАШИХ МОДЕЛЕЙ, КАК ПРИМЕР ТУТ БУДУТ КЛЮЧИ ОТ Google и OpenAI
# КЛЮЧЕЙ МОЖЕТ БЫТЬ СКОЛЬКО УГОДНО

# Google
GEMINI_API_KEY_1 = "Google_КЛЮЧ_1"
GEMINI_API_KEY_2 = "Google_КЛЮЧ_2"

# OpenAI
OpenAI_API_KEY = "OpenAI_КЛЮЧ"

5. Настройка config.yaml

В качестве примера приведу настройку config.yaml:

# config.yaml

model_list: # Определить модели и их группы
  - model_name: gemini-2.5-pro-exp-03-25 # Имя может быть любым
    litellm_params:
      model: gemini/gemini-2.5-pro-exp-03-25 # Реальная модель Gemini
      api_key: os.environ/GEMINI_API_KEY_1

  - model_name: gemini-2.5-pro-exp-03-25 # То же имя для балансировки
    litellm_params:
      model: gemini/gemini-2.5-pro-exp-03-25
      api_key: os.environ/GEMINI_API_KEY_2

  - model_name: gemini-2.0-flash-exp-image-generation # Группа для Flash модели
    litellm_params:
      model: gemini/gemini-2.0-flash-exp-image-generation
      api_key: os.environ/GEMINI_API_KEY_1

  - model_name: gemini-2.0-flash-exp-image-generation # То же имя для балансировки
    litellm_params:
      model: gemini/gemini-2.0-flash-exp-image-generation
      api_key: os.environ/GEMINI_API_KEY_2

  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY

  - model_name: o3-mini
    litellm_params:
      model: openai/o3-mini
      api_key: os.environ/OPENAI_API_KEY

router_settings:
  routing_strategy: simple-shuffle # Балансировка

database_settings:
  database_url: os.environ/DATABASE_URL

litellm_settings: # Основные настройки движка LiteLLM
  drop_params: True

general_settings: # Общие настройки прокси-сервера
  master_key: os.environ/LITELLM_MASTER_KEY
  litellm_proxy_admin_ui:
    enable: True
  completion_log_in_db: True
  disable_telemetry: True

Я не случайно выбрал ситуацию, в которой у вас оказалось два ключа от одной LLM (может быть сколько угодно). В этом случае вы можете настроить балансировку. Для этого необходимо указать один и тот же model_name и model, но разные api_key. А ниже в секции router_settings выбрать стратегию simple-shuffle. Перечисление возможностьей и отличий каждой стратегии уходит далеко за пределы этой статьи. Скажу лишь, что их всего четыре, это: «simple-shuffle», «least-busy», «usage-based-routing»,«latency-based-routing».

simple-shuffle случайным образом выбирает одно из доступных развертываний (т.е. один из ваших api-ключей). Это стратегия по умолчанию, которая хорошо подходит для малого количества ключей с одинаковыми лимитами, для одной модели.

Если у вас только по одному уникальному ключу. То секция router_settings не нужна!

Самое время запустить LiteLLM и посмотреть логи. В нём не должно быть никаких критических ошибок:

docker-compose up -d
docker logs -f litellm_litellm_1

Осталось сгенерировать «фейковые» ключи для LibreChat:

curl --location 'https://ВАШ DNS ИЛИ IP' \
--header 'Authorization: Bearer <СЮДА ПИСАТЬ ВАШ СГЕНЕРИРОВАННЫЙ ДЛЯ .env LITELLM_MASTER_KEY>' \
--header 'Content-Type: application/json' \
--data '{
    "models": ["gemini-2.5-pro-exp-03-25", "gemini-2.0-flash-exp-image-generation", "gpt-4o", "o3-mini"],
    "aliases": {},
    "max_budget_usd": null,
    "duration": null,
    "user_id": "librechat_my_virt_key",
    "metadata": {"description": "Key for my LibreChat"}
}'

LiteLLM вернет JSON-ответ, содержащий сгенерированный ключ в секции token, он будет начинаться с sk-. Сохраните этот ключ! Настройки nginx и LiteLLM завершены.


Возвращение к LibreChat

Ступайте обратно на свою локальную машину, на которой установлен и работает LibreChat. Идите в его каталог и создайте docker-compose.override.yml:

$ cp docker-compose.override.yml.example docker-compose.override.yml
$ touch librechat.yaml
$ vi docker-compose.override.yml

В нём нужно раскомментировать строки, чтобы получилось так:

services:
  api:
    volumes:
      - type: bind
        source: ./librechat.yaml
        target: /app/librechat.yaml

Файл librechat.yaml является основным конфигурационным файлом для приложения LibreChat. Он позволяет вам настраивать различные аспекты работы приложения централизованно, переопределяя стандартные настройки и значения, заданные в переменных окружения в .env.В нём вы можете указать ваши ендпойнты. То есть вы можете указать, как адреса и ключи коммерческих LLM, что вы настроивали в LiteLLM, так и локальных LLM, которые вам ещё только предстоит настроить.

Открывайте librechat.yaml и вносите туда модели, которые проксировали в LiteLLM :

#librechat.yaml
version: 6.6.6
cache: true
endpoints:
  agents:
    capabilities: ["execute_code", "file_search", "actions", "tools"]
  custom:
    - name: "OpenAI"
      iconURL: "openAI"
      apiKey: "${MYAPIKEY}"
      baseURL: "АДРЕС ВАШЕГО СЕРВЕРА С НАСТРОЕННЫМ LITELLM и NGINX"
      models:
        default: ["o3-mini", "gpt-4.5"] # Тут записаны openai модели из model_name config.yaml LiteLLM
        fetch: false
      titleConvo: true
      titleModel: "current_model"
      summarize: true
      summaryModel: "current_model"
      forcePrompt: false
    # modelDisplayLabel можно внести любое имя. Оно будет отображаться в чате.
      modelDisplayLabel: "gpt"
      dropParams: ["temperature"]
    - name: "Google"
      iconURL: "google"
      plugins: true
      apiKey: "${MYAPIKEY}"
      baseURL: "АДРЕС ВАШЕГО СЕРВЕРА С НАСТРОЕННЫМ LITELLM и NGINX"
      models:
        # Тут записаны google модели из model_name config.yaml LiteLLM
        default: ["gemini-2.5-pro-exp-03-25", "gemini-2.0-flash-exp-image-generation"]
        fetch: false
      titleConvo: true
      titleModel: "current_model"
      summarize: true
      summaryModel: "current_model"
      forcePrompt: false
      modelDisplayLabel: "gemini"
      dropParams: ["presence_penalty"]

Теперь открываете .env и вносите туда «фейковый» ключ, который вы создавали ранее в LiteLLM. Меняете настройки переменной ENDPOINTS, чтобы в LibreChat были доступны только агенты и ваши ендпойнты:

# ВОТ ЭТО НАДО ДОБАВИТЬ
MYAPIKEY="sk-ФЕЙКОВЫЙ КЛЮЧ"
# ВОТ ЭТО НАЙТИ И ИЗМЕНИТЬ
ENDPOINTS=custom,agents

УРА! вы закончили. Осталось только перезагрузить контейнеры, и после этого в LibreChat будут доступны ваши google и openai LLM (или те LLM, ключи от которых у вас есть):

$ docker-compose down
$ docker compose up -d

Всё? НЕТ, НЕ ВСЁ!


Часть третья: хитрая

До этого я говорил только о настройке и подключении коммерческих LLM, так же в первой части я упоминал загадочную настройку RAG. Самое время затронуть эти темы.

Да кто такая эта Ollama

Подробный разговор об Ollama это тема отдельной немалой статьи, поэтому большого перечисления возможностей, разнообразия моделей, системных требований к каждой модели и прочего тут не будет. Но раз я решил показать её простейшую интеграцию с LibreChat, то нужно дать хоть какое-то объяснение.

Ollama – это инструмент с открытым исходным кодом, который позволяет локально скачивать, настраивать и запускать LLM.

Ollama решает несколько важных задач и предлагает ряд преимуществ:

  • Простота: Она значительно упрощает сложный процесс установки и настройки LLM. Не нужно разбираться с зависимостями Python, версиями библиотек и т.д.
  • Локальный запуск:
  • Доступность: Делает мощные LLM доступными для разработчиков, исследователей и просто энтузиастов без необходимости платить за облачные api или иметь супермощные серверы (хотя для больших моделей всё-равно нужен мощный ПК).
  • Гибкость: Позволяет легко переключаться между разными моделями и пробовать их.
  • API для разработчиков: Ollama предоставляет локальный api, который позволяет интегрировать LLM в ваши собственные приложения.

Пока Ollama недоступна в большинтсве Linux-репозиториев, за исключением Arch, поэтому установка осуществляется так:

# если у вас arch
# без cuda
sudo pacman -S ollama
# c cuda
sudo pacman -S ollama-cuda
# для остальных
$ curl -fsSL https://ollama.com/install.sh | sh
# После установки
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now ollama

Полезно будет продемонстрировать несколько примеров:

Пример 1: Скачивание и первый запуск модели

Допустим, вы хотите попробовать какую-то модель.

$ ollama pull "какая-то модель"
$ ollama run "какая-то модель"

Если вы сразу попытаетесь запустить модель, которой у вас нет,

$ ollama run "другая какая-то модель

то:

1.  Ollama проверит, скачана ли она у вас.
2.  Если нет, но модель с таким названием существует, она автоматически скачает ее.
3.  После скачивания модель запустится, и вы увидите приглашение для ввода текста.
  • Как использовать:
    • Просто начните вводить свой вопрос или текст прямо в терминале и нажмите Enter.
    • Модель сгенерирует ответ.
    • Чтобы выйти из чата с моделью, введите команду /bye и нажмите Enter или Ctrl+С Ctrl+D.

Пример 2: Запуск конкретной версии или размера модели

Модели часто имеют разные размеры (например, 8 миллиардов параметров - 8b). Меньшие модели быстрее, но тупее, большие – тупее поменьше.

# Скачать и запустить Llama 3 с 8 миллиардами параметров
$ ollama pull llama3:8b
$ ollama run llama3:8b

# Чтобы увидеть, какие модели уже есть на вашем компьютере:
$ ollama list

Пример 3: Удаление модели

$ ollama rm llama3:8b

Пример 4: Если вы хотите получить ответ на один конкретный вопрос и сразу выйти

$ ollama run llama3:8b "Зачем я пишу эту статью в 3 часа ночи?"

Пример 5: Использование API

Ollama также запускает локальный веб-сервер (обычно по адресу http://localhost:11434), к которому можно отправлять запросы. Это полезно для интеграции со своими скриптами или приложениями.

curl http://localhost:11434/api/generate -d '{
  "model": "llama3:8b",
  "prompt": "Что такое теодицея?",
  "stream": false
}'

Подключение локальных LLM

Ну хватит примеров, пора подключать локальные LLM и RAG.

Снова открываете librechat.yaml и добавляете свою модель:

  custom:
    - name: "Ollama"
    # api ключ для Ollama используется как плейсхолдер, но для LibreChat эта запись нужна
      apiKey: "ollama"
    # Базовый URL для api Ollama. По умолчанию используется http://localhost:11434
    # Тут по идее настройки docker/podman будут разниться, вам может потребоваться настроить ollama так, чтобы она слушала все интерфейсы на 11434 порту
    # Если Ollama работает в Docker, или вы настроили работу, как в совете выше, то:
      baseURL: "http://host.docker.internal:11434/v1/chat/completions"
      models:
        default: ["llama3:8b"]
        fetch: true
      titleConvo: true
      titleModel: "current_model"
      summarize: false
      summaryModel: "current_model"
      forcePrompt: false
      modelDisplayLabel: "Ollama"

Перезагружаете LibreChat, теперь вам доступна llama3. А значит вы можете идти изучать список последних локальных LLM и их системные требования. (Важно понять, что если у вас полумёртвый ноутбук или пк времён, когда зумеры ещё не родились, то вся практическая третья часть скорее всего не для вас).

nvidia со своими cuda раскрывается лучше всего, а если у неё ещё много vram, то перед вами открываются очень широкие возможности. Но даже отсутствие nvidia не приговор. Локальные LLM могут работать на очень разном железе:

  • AMD c ROCm (с помощью неё по идее вы сможете запускать cuda)
  • CPU (вам понадобится много ram)

Системные требования

Привожу по просьбе @hobbit системные требования нескольких актуальных на данный момент локальных LLM:

Категория: Менее 4 млрд. параметров (<4B) (Ориентировочно: 2-8 Гб VRAM)

  • Llama-3.1-Minitron-4B

    • Уменьшенная и дообученная версия модели Llama 3.1 8B. Предназначена для работы на системах с сильно ограниченными ресурсами.
  • Phi-3-mini

    • Модель от Microsoft, демонстрирующая высокую производительность для своего размера (3.8B параметров). Подходит для задач, требующих сообразительности при минимальных ресурсах.
  • Gemma-2B

    • Наименьшая модель в линейке Gemma от Google. Разработана для запуска на устройствах с низкими вычислительными мощностями. Пользователи отмечают её конкурентоспособность даже по сравнению с некоторыми моделями 7-8B,
  • Qwen2-1.5B

    • Базовая модель из семейства Qwen2 с минимальным количеством параметров. Способна генерировать связный текст, являясь начальным уровнем для работы с LLM на очень слабых системах.

Категория: 7-12 млрд. параметров (7+B) (Ориентировочно: 8-16 Гб VRAM)

  • Mistral-Nemo-Instruct-2407-12B

    • Новая модель от Mistral AI (12B параметров). Заявлена как конкурент Gemma 27B по уровню сообразительности. Отличается высокой скоростью генерации и поддержкой контекстного окна 128k. Хорошо понимает инструкции и генерирует на русском языке. Из недостатков отмечаются повторяющиеся циклы («лупы») и наличие скрытых ограничений (bias). Ожидаются дообученные версии для устранения этих проблем.
  • Llama-3.1-8В

    • Обновленная версия Llama 3 (8B параметров), позиционируемая как часть модели 405B. По бенчмаркам разработчиков превосходит Gemma 9B, Mistral 7B и GPT-3.5 Turbo. Первоначальные тесты указывают на некоторую сухость стиля и наличие ограничений/bias, которые, по сообщениям, относительно легко обходятся. Поддерживает контекст 128k.
  • Gemma 2-9B

    • Обновленная версия Gemma от Google (9B параметров).
  • Qwen2-7B-Instruct

    • Модель из семейства Qwen2 (7B параметров), обученная следованию инструкциям.
  • Llama-3-8В

    • Базовая модель Llama 3 (8B параметров), оказавшая значительное влияние на сегмент малых LLM. Обладает неплохим уровнем русского языка, но может проявлять невнимательность к деталям инструкций и уступает моделям 30B+

Категория: ~30 млрд. параметров (~30B) (Ориентировочно: 12-36 Гб VRAM)

  • Mistral-Small-Instruct-2409 - 22B

    • Новая модель от Mistral AI среднего размера (22B параметров). Считается одной из лучших в своем классе на момент выхода.
  • Gemma 2-27B

    • Новая модель от Google (27B параметров). Отличается высоким качеством генерации на русском языке и производительностью, сравнимой с некоторыми 70B моделями. Однако имеет тенденцию к скрытым ограничениям/bias, которые могут проявляться со временем.
  • Qwen2.5-32B

    • Обновленная версия китайской модели Qwen (32B параметров). Поддерживает контекст 128k, показывает хорошие результаты в задачах кодирования.

Категория: ~70 млрд. параметров (~70B) (Ориентировочно: 24-64 Гб VRAM)

  • Llama-3.3-70В

    • Новейшее обновление Llama 3 в размере 70B. Заявлено, что производительность находится на уровне Llama-3.1-405B, однако по пользовательским отчетам уступает Qwen2.5-72B. Поддерживает контекстное окно 128k.
  • Llama-3.1-70В

    • Обновление Llama 3 (70B параметров), считается частью (обрезанной версией) 405B модели. По бенчмаркам разработчиков превосходит GPT-3.5 Turbo. Поддерживает контекст 128k.
  • Qwen2-72B

    • Китайская модель (72B параметров), позиционируемая как превосходящая Llama 3 70B, присутствует цензура. Однако существуют мнения, что она уступает Llama 3 в практических задачах и медленнее из-за особенностей механизма внимания. Есть подозрения на завышение результатов в бенчмарках и наличие сильных ограничений/bias.

Категория: >100 млрд. параметров (100B+) (Ориентировочно: >64 Гб VRAM, требует мощных конфигураций)

  • Mistral-Large-123B

    • Обновление линейки Mistral (123B параметров). Скорость генерации приемлемая (~10-12 токенов/сек на соответствующем оборудовании). Очень сильная локальная модель, отмечается её превосходство над Llama 70B и её дообученными версиями.
  • Meta-Llama-3.1-405B

    • Самая крупная модель 3 поколения от Meta (405B параметров). Является базовой версией, из которой получены модели 70B и 8B. Заявленный уровень производительности — GPT-4 / Claude 3 Sonnet (что оспаривается пользователями). Первые тесты указывают на наличие сильных ограничений/bias («соя»), но они обходятся. Поддерживает контекстное окно 128k. Требует очень мощного оборудования.

На момент написания этой статьи вышли новые gemma 3 и Llama-4, а так же дистиляты DeepSeek разных вариаций. Предоставление подробной информации об их различиях, системных требований и прочего далеко уходит за грань этой статьи. И писать такую статью я не собираюсь (скорость выхода и развития новых моделей так высока, что это бессмысленно).


ХУ ИЗ RAG

RAG (Retrieval-Augmented Generation, что можно перевести как «Генерация, дополненная поиском») – это подход, который объединяет возможности большой языковой модели (LLM) по генерации текста с внешней системой поиска (retrieval) информации. Вместо того чтобы полагаться только на знания, зашитые в LLM во время ее обучения, RAG позволяет модели перед генерацией ответа сначала найти актуальную и релевантную информацию из заданного набора источников данных.

Если в LibreChat настроен RAG, то у вас появляется возможноть во время общения с LLM прикрепить текстовый файл (поддерживается множество форматов), чтобы сформировать запрос, связанный с информацией из текстового файла. Этот текстовый файл не будет напрямую передан LLM, а будет отправлен на индексацию во внешнюю (локальную или облачную) нейросеть (обычно не LLM), которая проиндексирует весь файл в семантические векторы (или эмбеддинги) и вернёт в LLM лишь часть информации, которая должна соответствовать вашему запросу, эту часть информации и будет обрабатывать LLM для формирования своего ответа.

Для локальной работы вы должны установить nomic-embed-text через ollama:

$ ollama pull nomic-embed-text

nomic-embed-text – это специализированная нейросеть, классифицируемая как модель текстовых эмбеддингов, которая преобразует текст в числовые векторы для задач семантического поиска и является ключевым компонентом в «Retrieval» (поиске) части RAG-систем.

Теперь открываете docker-compose.override.yml и дополняете его:

services:
  rag_api:
    image: ghcr.io/danny-avila/librechat-rag-api-dev:latest

Для работы с локальным RAG нужно установить контейнер с расширенным функционалом.

После вносите изменение в .env

RAG_API_URL=http://host.docker.internal:8000
EMBEDDINGS_PROVIDER=ollama
# Тут по идее настройки docker/podman будут разниться, вам может потребоваться настроить ollama так, чтобы она слушала все интерфейсы на 11434 порту
OLLAMA_BASE_URL=http://host.docker.internal:11434
EMBEDDINGS_MODEL=nomic-embed-text

Готово, теперь всё должно работать. Перезагружайте docker-compose, настройка завершена.


Я ещё не договорил

Очень важный момент. LLM не делает служебный запрос для поиска RAG в базовом сценарии (агенты могут работать иначе). Ваш начальный промпт обрабатывается не основной нейросетью, а той, что настроена для работы с RAG. Она не может переформулировать ваш запрос, соответственно, если пользователь задает очень общий, неоднозначный, многосоставный или просто плохо сформулированный вопрос, векторизация этого может привести к поиску нерелевантных фрагментов, которые и будут переданы основной LLM. RAG – это компромисс, который придуман для того, чтобы вы могли передать LLM текст, размер которого превышает контекстное окно LLM.

Самые передовые коммерческие LLM обладают очень большим контекстым окном, теперь они могут принять огромные объёмы текста, минуя этот компромисс (это будет стоить вам дороже). В актуальном LibreChat v0.7.7 пока нет возможности прикрепить файл, минуя RAG. Эта функция должна быть добавлена в v0.7.8/9

Если вас интересует на базовом уровне, как выглядит взаимодействие с RAG:

  • Фаза 1: Индексация документа (когда вы прикрепляете впервые файл)
  1. Загрузка файла (Пользователь -> LibreChat):
    • Вы выбираете и прикрепляете текстовый файл (например, PDF, TXT, DOCX) в интерфейсе LibreChat.
  2. Отправка файла в RAG (LibreChat -> rag_api):
    • LibreChat получает файл.
    • Понимая, что этот файл предназначен для RAG, LibreChat отправляет содержимое этого файла (или ссылку на него, если он временно сохранен) на эндпоинт вашего rag_api (который слушает на http://host.docker.internal:8000).
  3. Обработка и Чанкинг (rag_api):
    • Сервис rag_api получает текстовые данные из файла.
    • Он разбивает (chunking) весь текст документа на более мелкие, управляемые фрагменты. Размер и метод разбивки (по параграфам, предложениям, с перекрытием) настраиваются в rag_api. Это важно, так как эмбеддинги создаются для каждого чанка отдельно, а не для всего документа целиком.
  4. Запрос на создание Эмбеддингов (rag_api -> Ollama):
    • Для каждого текстового чанка rag_api формирует запрос к Ollama.
    • Основываясь на ваших .env, rag_api отправляет api-запрос на http://host.docker.internal:11434 с текстом чанка, указывая, что нужно использовать модель nomic-embed-text для генерации эмбеддинга.
  5. Генерация Эмбеддингов:
    • Ollama получает запрос от rag_api.
    • Запускает модель nomic-embed-text.
    • Модель обрабатывает текст чанка и генерирует числовой вектор, представляющий семантическое значение этого чанка.
    • Ollama возвращает этот вектор обратно сервису rag_api.
    • Этот процесс повторяется для всех чанков документа.
  6. Сохранение в Векторную Базу (rag_api -> vectordb):
    • rag_api получает вектор от Ollama для каждого чанка.
    • rag_api подключается к вашей vectordb.
    • Для каждого чанка rag_api сохраняет в vectordb:
      • Сгенерированный вектор.
      • Оригинальный текст этого чанка.
      • Метаданные.
  7. Завершение Индексации: Процесс завершен. Векторные представления вашего документа теперь хранятся в vectordb и готовы к поиску. LibreChat может показать вам, что файл обработан.
  • Фаза 2: Запрос к базе данных
  1. Формулировка Запроса (Пользователь -> LibreChat):
    • Вы задаете вопрос в чате LibreChat, указывая, что ответ нужно искать с использованием прикрепленных ранее файлов.
  2. Передача Запроса в RAG api (LibreChat -> rag_api):
    • LibreChat отправляет ваш текстовый запрос в rag_api.
  3. Создание Эмбеддинга для Запроса (rag_api -> Ollama):
    • rag_api берет ваш вопрос и отправляет его в Ollama для создания эмбеддинга с использованием той же самой модели nomic-embed-text. Крайне важно использовать одну и ту же модель для индексации и для запросов.
  4. Генерация Эмбеддинга Запроса:
    • Ollama генерирует векторное представление вашего вопроса и возвращает его в rag_api.
  5. Поиск Похожих Веторов (rag_api -> vectordb):
    • rag_api использует полученный вектор запроса для поиска в vectordb.
    • Оно выполняет поиск семантической близости, чтобы найти N векторов, которые наиболее близки по смыслу к вектору вашего вопроса.
  6. Извлечение Контекста (rag_api -> vectordb -> rag_api):
    • rag_api получает из vectordb тексты тех чанков, чьи векторы оказались наиболее релевантными запросу. Это и есть извлеченный контекст.
  7. Возврат Контекста в LibreChat (rag_api -> LibreChat):
    • rag_api отправляет найденные релевантные текстовые чанки обратно в основной сервис LibreChat.
  8. Формирование Промпта для LLM:
    • LibreChat получает контекст от rag_api.
    • Он конструирует финальный промпт для LLM. Этот промпт обычно включает:
      • Системные инструкции.
      • Извлеченный контекст (текст релевантных чанков).
      • Ваш оригинальный вопрос.

Финал

Я познакомил вас с LibreChat, его базовой настройкой и функционалом. Специально для вас, я прошёлся только по самым верхам, поэтому мной совсем не затронута тема агентов и инструментов к ним, установка и взаимодействие со встроенным интерпретатором кода и многое другое. Особая благодарность админу-корректору, которому пришлось вычитать этот текст до конца. Возможно ты мой единственный зритель.

Источники:



Проверено: maxcom ()
Последнее исправление: dataman (всего исправлений: 9)

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

А можно вместо шуточек про зумеров написать конкретнее, какие требования к железу, чтобы более-менее комфортно с этим работать? Про желательность наличия CUDA я понял, что ещё?

hobbit ★★★★★
()
Ответ на: комментарий от hobbit

Для вас @hobbit можно всё. Хорошо, я внесу изменения в эту часть. Если есть вопросы ещё к чёму-то, то укажи.

mamina_radost
() автор топика

Хотел ещё скастовать сюда @rtxtxtrx, но он разочаровался в ЛОРе и больше тут не появляется.

Придётся перечитывать (и возможно, пробовать) самому…

hobbit ★★★★★
()
Ответ на: комментарий от hobbit

Это полезно, давай. Жаль такую маленькую статью написал. Знал бы, что все так перепроверять будешь, писал бы больше. Например кроме vps можно проки развернуть силами самой Hugging Face.

mamina_radost
() автор топика
Ответ на: комментарий от mamina_radost

писал бы больше

Можно еще написать, что можно делать с этим великолепием. Я вот поставил LibreChat до твоего гайда без проблем (подключил через апи), но вот про RAG не знал. Ну там какие есть агенты, какие плагины для ide, какие дополнительные тулзы и т.д. Чтобы хоть знать, что еще есть, а уж с установкой как-то можно разобраться.

goingUp ★★★★★
()
Ответ на: комментарий от goingUp

Статья о возможностях LibreChat не имела бы смысл, если бы не была написана статья о том, что это такое и как его ставить. Размер статьи о возможностях будет не меньше этой. Может быть я её напишу, если эта статья, когда её подтвердят, получит тут отклик.

mamina_radost
() автор топика
Ответ на: комментарий от mamina_radost

Вот только, к сожалению, раньше, чем через неделю, до проверки руки у меня уже не дойдут. И так уже долго статья висит, да.

Может быть, кто-то ещё из подтверждающих возьмётся…

hobbit ★★★★★
()
Ответ на: комментарий от hobbit

Шо поделать. Когда проверишь, тогда проверишь.

Может быть, кто-то ещё из подтверждающих возьмётся…

Вряд ли, ЛОР совсем скукожился. Не выдерживает вызовов истории. Я поэтому и написал статью, эта тема тут почти не освещалась.

mamina_radost
() автор топика

Любопытно. Было-бы еще более любопытно, если бы в статье отсутствовал докер. Потому как по мне - он тут просто не нужен. Тем паче, что на сайте есть вариант установки и без оного.

DrRulez ★★★★★
()
Ответ на: комментарий от mamina_radost

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

Тогда зачем эта простыня с костылями ?

DrRulez ★★★★★
()
Ответ на: комментарий от DrRulez

простыня с костылями

Вы что-то путаете, тут нет описания установки, через npm в локальной неизолированной системе.

mamina_radost
() автор топика
Последнее исправление: mamina_radost (всего исправлений: 1)

Автор, ты сам всё это написал или скопипастил откуда-то? Я даже прочитать не осилил столько букв.

Ну и да, докеры дополнительно портят впечатление.

firkax ★★★★★
()
Ответ на: комментарий от firkax

сам всё это написал или скопипастил

Я думаю это легко верифицировать. Если копия с русского, то кроме хабра мало откуда можно скопировать. С переводом немного сложнее, но в несколько кликов можно разобраться.

Писал сам с помощью самих же llm. Описание локальнх нейронок и rag, составляла нейросеть, это по структуре даже видно. Я задавал промпт и проверял. Лучше и схематичней, чем llm эти части не написать, да и тема статьи благоволит.

не осилил столько букв.

Это уже вопросы почему ЛОР такое {{подставьте сюда оскорбительное слово}}, которое не приспособлено к написанию статей сложнее установки dosbox из репозитория. Были бы возможности добавлять фото по ходу описания, составлять раскрывающиеся списки и добовлять ссылки в введении, как на вики, то было бы хорошо.

mamina_radost
() автор топика

docker

podman

А я-то думал речь действительно пойдёт о развёртыванИИ. (%

mord0d ★★★★★
()
Ответ на: комментарий от mamina_radost

Т.к. статья относительно большая, то можно было бы в начале разместить список подразделов.

Писал сам с помощью самих же llm. Описание локальнх нейронок и rag, составляла нейросеть, это по структуре даже видно. Я задавал промпт и проверял.

Полагаю, что в этом случае следует нейросеть в соавторах указывать.

MirandaUser2
()
Ответ на: комментарий от pekmop1024

На самом деле это не такой простой вопрос. Я довольно давно и совсем немного взаимодействовал с openwebui, сейчас он выглядит сильно круче, так что буду изучать подробно для сравнения. Но пока я вижу ряд отличий, и кажется, к сожалению, что в каждом из этих инструментов есть что-то своё, а хотелось бы чтобы они оба это умели.

Например в librechat точно есть такая штука, как Artifacts - рендеринг HTML/React компонентов в чате. Но в openwebui есть пайплайны, выглядит интересно. Так же я заметил, что openwebui критикуют за не самую лучшую архитектуру обращения к базе данных. Буду честен, не знаю как устроена в openwebui работа с MCP. Может openwebui сейчас даже лучше. Спасибо, что напомнил о нём, буду изучать.

mamina_radost
() автор топика
Последнее исправление: mamina_radost (всего исправлений: 2)
Ответ на: комментарий от pekmop1024

А какие преимущества по сравнению с Open WebUI?

Изучил Open WebUI, ответ на ваш вопрос librechat всем хуже. Единственное, что вставка кастомных перменных {{variable}} в промпт в librechat сделана явно лучше и удобнее.

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

mamina_radost
() автор топика
Ответ на: комментарий от pekmop1024

В LibreChat MIT License. А в Open WebUI теперь чудеса:

1. Основные положения новой лицензии Open WebUI (версия 0.6.6+ от апреля 2025 года) [1]:

  • Основа лицензии: Новая лицензия базируется на BSD-3-Clause, которая является разрешительной (permissive) лицензией.
  • Ключевое добавление – защита брендинга:
    • Запрещено изменять, удалять или скрывать любой брендинг «Open WebUI» (название, логотип, элементы интерфейса и т.д.) при любом развертывании или распространении проекта.
    • Брендинг должен оставаться четко видимым.
  • Исключения из правила о сохранении брендинга (когда брендинг можно изменять/удалять):
    1. Если у вас 50 или менее пользователей в 30-дневный период.
    2. Если вы являетесь контрибьютором проекта и получили письменное разрешение от команды Open WebUI.
    3. Если вы приобрели корпоративную (enterprise) лицензию, которая явно разрешает изменения брендинга.
  • Старый код: Весь код, внесенный в проект и включенный в релизы до версии v0.6.5 (включительно), остается под оригинальной лицензией BSD-3, и требование о сохранении брендинга на него не распространяется.
  • CLA (Contributor License Agreement): Для всех новых вкладов в код (начиная с версии v0.6.6 и далее) требуется подписание соглашения о лицензировании вклада (CLA).

Ребята делают задел на полную закрытость. Open WebUI идёт по стопам другой открытой компании – openai. Вот это особенно хорошо сейчас в лицензии Open WebUI.

Некоторые положения, например, одновременное требование сохранять брендинг и запрет на использование имени для продвижения форка

mamina_radost
() автор топика
Последнее исправление: mamina_radost (всего исправлений: 2)

Очень многа буков, я набираю в консоли tgpt -m.

IPR ★★★★★
()
Ответ на: комментарий от somemong

Ты прав, с его api тоже будет работать без проксей.

mamina_radost
() автор топика

Видел что это уже висит, ооч давно, но только сейчас прочитал что на картинке, взоржал =)

LINUX-ORG-RU ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.