# 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](https://docs.clore.ai/guides/guides_v2-ru/yazykovye-modeli/llamacpp-server) - Кроссплатформенный
* [Text Generation WebUI](https://docs.clore.ai/guides/guides_v2-ru/yazykovye-modeli/text-generation-webui) - Веб-интерфейс
