# ExLlamaV2

Запускайте LLM на максимальной скорости с ExLlamaV2.

{% hint style="success" %}
Все примеры можно запускать на GPU-серверах, арендуемых через [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

## Аренда на CLORE.AI

1. Посетите [CLORE.AI Marketplace](https://clore.ai/marketplace)
2. Отфильтруйте по типу GPU, объему VRAM и цене
3. Выберите **On-Demand** (фиксированная ставка) или **Spot** (цена по ставке)
4. Настройте ваш заказ:
   * Выберите Docker-образ
   * Установите порты (TCP для SSH, HTTP для веб-интерфейсов)
   * Добавьте переменные окружения при необходимости
   * Введите команду запуска
5. Выберите способ оплаты: **CLORE**, **BTC**, или **USDT/USDC**
6. Создайте заказ и дождитесь развертывания

### Доступ к вашему серверу

* Найдите данные для подключения в **Моих заказах**
* Веб-интерфейсы: используйте URL HTTP-порта
* SSH: `ssh -p <port> root@<proxy-address>`

## Что такое ExLlamaV2?

ExLlamaV2 — самый быстрый движок для инференса больших языковых моделей:

* В 2–3 раза быстрее других движков
* Отличная количественная оценка (EXL2)
* Низкое потребление видеопамяти (VRAM)
* Поддерживает спекулятивное декодирование

## Требования

| Размер модели | Мин. VRAM | Рекомендуется |
| ------------- | --------- | ------------- |
| 7B            | 6 ГБ      | RTX 3060      |
| 13B           | 10GB      | RTX 3090      |
| 34B           | 20GB      | RTX 4090      |
| 70B           | 40GB      | A100          |

## Быстрое развертывание

**Docker-образ:**

```
pytorch/pytorch:2.5.1-cuda12.4-cudnn9-devel
```

**Порты:**

```
22/tcp
8080/http
```

**Команда:**

```bash
pip install exllamav2 && \
huggingface-cli download turboderp/Llama2-7B-exl2 --local-dir ./model && \
python -m exllamav2.server --model_dir ./model --host 0.0.0.0 --port 8080
```

## Доступ к вашему сервису

После развертывания найдите ваш `http_pub` URL в **Моих заказах**:

1. Перейдите на **Моих заказах** страницу
2. Нажмите на ваш заказ
3. Найдите `http_pub` URL (например, `abc123.clorecloud.net`)

Используйте `https://YOUR_HTTP_PUB_URL` вместо `localhost` в примерах ниже.

## Установка

```bash

# Установить из PyPI
pip install exllamav2

# Или из исходников (последние функции)
git clone https://github.com/turboderp/exllamav2
cd exllamav2
pip install .
```

## Загрузка моделей

### Квантованные модели EXL2

```bash

# Llama 3.1 8B (4.0 bpw)
huggingface-cli download turboderp/Llama2-7B-exl2 \
    --revision 4.0bpw \
    --local-dir ./llama2-7b-exl2

# Llama 3.1 8B (4.0 bpw)
huggingface-cli download turboderp/Llama2-13B-exl2 \
    --revision 4.0bpw \
    --local-dir ./llama2-13b-exl2

# Mistral 7B (4.0 bpw)
huggingface-cli download turboderp/Mistral-7B-instruct-exl2 \
    --revision 4.0bpw \
    --local-dir ./mistral-7b-exl2

# Mixtral 8x7B
huggingface-cli download turboderp/Mixtral-8x7B-instruct-exl2 \
    --revision 4.0bpw \
    --local-dir ./mixtral-exl2
```

### Биты на вес (bpw)

| BPW | Качество      | VRAM (7B) |
| --- | ------------- | --------- |
| 2.0 | Низкая        | \~3ГБ     |
| 3.0 | Хорошо        | \~4ГБ     |
| 4.0 | Отлично       | \~5ГБ     |
| 5.0 | Отлично       | \~6ГБ     |
| 6.0 | Близко к FP16 | \~7ГБ     |

## Python API

### Базовая генерация

```python
from exllamav2 import ExLlamaV2, ExLlamaV2Config, ExLlamaV2Cache, ExLlamaV2Tokenizer
from exllamav2.generator import ExLlamaV2StreamingGenerator, ExLlamaV2Sampler

# Загрузить модель
config = ExLlamaV2Config()
config.model_dir = "./llama2-7b-exl2"
config.prepare()

model = ExLlamaV2(config)
model.load()

tokenizer = ExLlamaV2Tokenizer(config)
cache = ExLlamaV2Cache(model, lazy=True)

# Создать генератор
generator = ExLlamaV2StreamingGenerator(model, cache, tokenizer)

# Установить параметры сэмплинга
settings = ExLlamaV2Sampler.Settings()
settings.temperature = 0.7
settings.top_k = 50
settings.top_p = 0.9

# Генерация
prompt = "Будущее искусственного интеллекта — это"
output = generator.generate_simple(prompt, settings, num_tokens=200)
print(output)
```

### Потоковая генерация

```python
from exllamav2.generator import ExLlamaV2StreamingGenerator

generator = ExLlamaV2StreamingGenerator(model, cache, tokenizer)

prompt = "Напишите короткий рассказ о роботе:"
input_ids = tokenizer.encode(prompt)

generator.set_stop_conditions([tokenizer.eos_token_id])
generator.begin_stream(input_ids, settings)

while True:
    chunk, eos, _ = generator.stream()
    if eos:
        break
    print(chunk, end="", flush=True)
```

### Формат чата

```python
def format_chat(messages):
    text = ""
    for msg in messages:
        role = msg["role"]
        content = msg["content"]
        if role == "system":
            text += f"[INST] <<SYS>>\n{content}\n<</SYS>>\n\n"
        elif role == "user":
            text += f"{content} [/INST]"
        elif role == "assistant":
            text += f" {content}</s><s>[INST] "
    return text

messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Что такое Python?"}
]

prompt = format_chat(messages)
output = generator.generate_simple(prompt, settings, num_tokens=300)
```

## Режим сервера

### Запустить сервер

```bash
python -m exllamav2.server \
    --model_dir ./llama2-7b-exl2 \
    --host 0.0.0.0 \
    --port 8080 \
    --max_seq_len 4096 \
    --cache_size 4096
```

### Использование API

```python
import requests

response = requests.post(
    "http://localhost:8080/v1/completions",
    json={
        "prompt": "Привет, как дела?",
        "max_tokens": 100,
        "temperature": 0.7
    }
)

print(response.json()["choices"][0]["text"])
```

### Завершения чата

```python
import openai

client = openai.OpenAI(
    base_url="http://localhost:8080/v1",
    api_key="не_требуется"
)

response = client.chat.completions.create(
    model="llama2-7b",
    messages=[{"role": "user", "content": "Привет!"}],
    temperature=0.7
)

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

## TabbyAPI (рекомендуемый сервер)

TabbyAPI предоставляет функционально насыщенный сервер ExLlamaV2:

```bash

# Клонировать TabbyAPI
git clone https://github.com/theroyallab/tabbyAPI
cd tabbyAPI

# Установить
pip install -r requirements.txt

# Настроить

# Отредактируйте config.yml с путем к вашей модели

# Запустить
python main.py
```

### Функции TabbyAPI

* Совместимый с API OpenAI
* Поддержка нескольких моделей
* Горячая смена LoRA
* Потоковая передача (Streaming)
* Вызов функций
* API администратора

## Спекулятивная декодировка

Используйте меньшую модель для ускорения генерации:

```python
from exllamav2 import ExLlamaV2, ExLlamaV2Config, ExLlamaV2Cache

# Загрузить основную модель (13B)
main_config = ExLlamaV2Config()
main_config.model_dir = "./llama2-13b-exl2"
main_config.prepare()
main_model = ExLlamaV2(main_config)
main_model.load()

# Загрузить черновую модель (7B)
draft_config = ExLlamaV2Config()
draft_config.model_dir = "./llama2-7b-exl2"
draft_config.prepare()
draft_model = ExLlamaV2(draft_config)
draft_model.load()

# Создать спекулятивный генератор
from exllamav2.generator import ExLlamaV2DraftGenerator

generator = ExLlamaV2DraftGenerator(
    main_model, draft_model,
    cache_main, cache_draft,
    tokenizer
)

# Генерация (быстрее со спекуляцией)
output = generator.generate_simple(prompt, settings, num_tokens=500)
```

## Квантование ваших моделей

### Конвертировать в EXL2

```python
from exllamav2 import ExLlamaV2, ExLlamaV2Config
from exllamav2.conversion import convert_model

# Источник: модель HuggingFace

# Цель: квантованная EXL2

convert_model(
    input_dir="./llama-3.1-8b-hf",
    output_dir="./llama-3.1-8b-exl2-4bpw",
    cal_dataset="wikitext",  # Датасет для калибровки
    bits=4.0,  # Биты на вес
    head_bits=6,  # Более высокая точность для внимания
)
```

### Командная строка

```bash
python convert.py \
    -i ./llama-3.1-8b-hf \
    -o ./llama-3.1-8b-exl2 \
    -cf ./llama-3.1-8b-exl2 \
    -b 4.0 \
    -hb 6
```

## Управление памятью

### Распределение кэша

```python

# Фиксированный размер кэша
cache = ExLlamaV2Cache(model, max_seq_len=4096)

# Динамический кэш
cache = ExLlamaV2Cache(model, lazy=True)
cache.current_seq_len = 0  # Растет по необходимости
```

### Мульти-GPU

```python
config = ExLlamaV2Config()
config.model_dir = "./large-model"

# Разделение по GPU
config.set_auto_split([0.5, 0.5])  # 50% на каждый GPU

model = ExLlamaV2(config)
model.load()
```

## Сравнение производительности

| Модель       | Движок    | GPU      | Токенов/с |
| ------------ | --------- | -------- | --------- |
| Llama 3.1 8B | ExLlamaV2 | RTX 3090 | \~150     |
| Llama 3.1 8B | llama.cpp | RTX 3090 | \~100     |
| Llama 3.1 8B | vLLM      | RTX 3090 | \~120     |
| Llama 3.1 8B | ExLlamaV2 | RTX 3090 | \~90      |
| Mixtral 8x7B | ExLlamaV2 | A100     | \~70      |

## Расширенные настройки

### Параметры сэмплинга

```python
settings = ExLlamaV2Sampler.Settings()
settings.temperature = 0.7
settings.top_k = 50
settings.top_p = 0.9
settings.token_repetition_penalty = 1.1
settings.token_frequency_penalty = 0.0
settings.token_presence_penalty = 0.0
settings.mirostat = False
settings.mirostat_tau = 5.0
settings.mirostat_eta = 0.1
```

### Пакетная генерация

```python
prompts = [
    "Смысл жизни —",
    "Искусственный интеллект будет",
    "Изменение климата —"
]

outputs = []
for prompt in prompts:
    output = generator.generate_simple(prompt, settings, num_tokens=100)
    outputs.append(output)
```

## Устранение неполадок

### Ошибка CUDA: недостаточно памяти

```python

# Использовать меньший кэш
cache = ExLlamaV2Cache(model, max_seq_len=2048)

# Или модель с меньшим bpw (3.0 вместо 4.0)
```

### Медленная загрузка

```python

# Включить быструю загрузку
config.fasttensors = True
```

### Модель не найдена

```bash

# Проверьте, что файлы модели существуют
ls ./model/

# Должно содержать: config.json, *.safetensors, tokenizer.json
```

## Интеграция с LangChain

```python
from langchain.llms.base import LLM
from typing import Optional, List

class ExLlamaV2LLM(LLM):
    model: ExLlamaV2
    tokenizer: ExLlamaV2Tokenizer
    generator: ExLlamaV2StreamingGenerator
    settings: ExLlamaV2Sampler.Settings

    @property
    def _llm_type(self) -> str:
        return "exllamav2"

    def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
        return self.generator.generate_simple(prompt, self.settings, num_tokens=500)

# Пример использования
llm = ExLlamaV2LLM(model=model, tokenizer=tokenizer, generator=generator, settings=settings)
result = llm("Что такое квантовые вычисления?")
```

## Оценка стоимости

Типичные ставки на маркетплейсе CLORE.AI (по состоянию на 2024):

| GPU       | Почасовая ставка | Дневная ставка | Сессия 4 часа |
| --------- | ---------------- | -------------- | ------------- |
| RTX 3060  | \~$0.03          | \~$0.70        | \~$0.12       |
| RTX 3090  | \~$0.06          | \~$1.50        | \~$0.25       |
| RTX 4090  | \~$0.10          | \~$2.30        | \~$0.40       |
| A100 40GB | \~$0.17          | \~$4.00        | \~$0.70       |
| A100 80GB | \~$0.25          | \~$6.00        | \~$1.00       |

*Цены варьируются в зависимости от провайдера и спроса. Проверьте* [*CLORE.AI Marketplace*](https://clore.ai/marketplace) *для текущих тарифов.*

**Экономьте деньги:**

* Используйте **Spot** рынок для гибких рабочих нагрузок (часто на 30–50% дешевле)
* Платите с помощью **CLORE** токенов
* Сравнивайте цены у разных провайдеров

## Дальнейшие шаги

* vLLM Inference — высокопроизводительное развёртывание
* [Сервер llama.cpp](/guides/guides_v2-ru/yazykovye-modeli/llamacpp-server.md) - Кроссплатформенный
* [Text Generation WebUI](/guides/guides_v2-ru/yazykovye-modeli/text-generation-webui.md) - Веб-интерфейс


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-ru/yazykovye-modeli/exllamav2-fast.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
