- BrainTools - https://www.braintools.ru -

Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces

Каждый раз, когда кто-то говорит про запуск LLM, возникает вопрос: “А где взять GPU?” Облачные GPU стоят денег, локальные видеокарты стоят ещё больших денег, а бесплатные GPU-тиры исчезают быстрее, чем появляются.

Но что если можно запустить полноценного AI-ассистента вообще без GPU? На обычном CPU. Бесплатно. С хорошей поддержкой русского языка. И развернуть его за 15-20 минут.

Эта статья адресована начинающим специалистам в области машинного обучения [1] и data science. Если вы только знакомитесь с экосистемой ML-инструментов, здесь вы найдёте подробное введение в два замечательных инструмента: Gradio для создания веб-интерфейсов к ML-моделям и Hugging Face Spaces для бесплатного хостинга демо-приложений. Никаких глубоких знаний веб-разработки не требуется — только базовый Python.

Звучит слишком хорошо, чтобы быть правдой, но это работает. В этой статье:

  • Разворачивается модель Qwen2.5-3B-Instruct на бесплатном CPU-тире Hugging Face Spaces

  • Создаётся веб-интерфейс чата с помощью Gradio

  • Генерируется публичная ссылка, которой можно поделиться с кем угодно

  • Разбирается каждая строчка кода, чтобы было понятно, что происходит под капотом

Всё, что нужно: Python, аккаунт на Hugging Face и 15-20 минут времени.

TL;DR

Тема

Содержание

Что создаётся

AI-ассистент с веб-интерфейсом чата

Модель

Qwen2.5-3B-Instruct (квантизация Q4_K_M)

Технологии

Gradio + llama-cpp-python + Hugging Face Spaces

Требования

Python 3.10+, аккаунт на Hugging Face

Время

~15-20 минут

Стоимость

Бесплатно

Результат

Публичная ссылка на работающего чат-бота

Что такое Gradio

Gradio — это open-source Python-библиотека для создания веб-интерфейсов к машинному обучению. Звучит сухо, но на практике это означает: вы можете превратить любую Python-функцию в полноценное веб-приложение за несколько строк кода. Без HTML. Без CSS. Без JavaScript. Просто Python.

Быстрый старт

Установка:

pip install gradio
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 1 [2]

Создайте файл app.py:

import gradio as gr

def greet(name):
    return f"Привет, {name}!"

demo = gr.Interface(fn=greet, inputs="text", outputs="text")
demo.launch()
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 2 [2]

Запуск:

python app.py
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 3 [2]

Четыре строки кода — и у вас есть веб-страница с текстовым полем, кнопкой и областью вывода. После запуска браузер откроется на http://127.0.0.1:7860 с готовым интерфейсом.

Три уровня абстракции

Gradio предлагает три способа создания интерфейсов, от простого к сложному:

gr.Interface — самый простой вариант. Одна функция, входы, выходы. Идеально для быстрых демо: классификация изображений, генерация текста, предсказания модели.

gr.ChatInterface — специализированный интерфейс для чат-ботов. Из коробки получаете историю сообщений, поле ввода, примеры запросов. Именно его мы используем в этом проекте.

gr.Blocks — полный контроль над layout. Можно создавать сложные интерфейсы с несколькими колонками, табами, условной логикой [3]. Требует больше кода, но даёт больше гибкости.

Компоненты

В Gradio более 40 готовых компонентов. Самые популярные:

Компонент

Назначение

gr.Textbox

Текстовый ввод/вывод

gr.Image

Загрузка и отображение изображений

gr.Audio

Работа с аудиофайлами

gr.Video

Видео-контент

gr.Chatbot

Чат с историей сообщений

gr.Slider

Ползунок для числовых значений

gr.Dropdown

Выпадающий список

gr.File

Загрузка файлов

gr.DataFrame

Таблицы данных

gr.Plot

Графики (matplotlib, plotly)

Компоненты можно комбинировать в любых сочетаниях. Хотите загрузить изображение и получить текстовое описание? inputs=gr.Image(), outputs=gr.Textbox(). Хотите голосовой ввод с текстовым ответом? inputs=gr.Audio(), outputs=gr.Textbox().

Почему Gradio, а не Streamlit

Оба инструмента решают похожую задачу, но есть важные отличия:

Для чат-ботов Gradio удобнее. gr.ChatInterface — это готовое решение для conversational AI. В Streamlit придётся собирать чат вручную из st.chat_message и управлять состоянием через st.session_state.

Интеграция с Hugging Face. Gradio создан той же командой, что и Hugging Face Hub. Деплой на Spaces работает бесшовно, а модели с Hub подключаются в одну строку.

Share-ссылки. Запустите demo.launch(share=True), и Gradio создаст публичную ссылку, которая работает 72 часа. Удобно для быстрых демонстраций без деплоя.

API из коробки. Каждое Gradio-приложение автоматически получает REST API. Можно вызывать вашу модель программно, не только через веб-интерфейс.

Что под капотом

Gradio использует FastAPI для бэкенда и Svelte для фронтенда. При запуске demo.launch() поднимается локальный веб-сервер, который обрабатывает запросы и вызывает вашу Python-функцию.

Когда вы деплоите на Hugging Face Spaces, происходит то же самое — только сервер работает в облаке, а не на вашей машине.

Что такое Hugging Face Spaces

Hugging Face Spaces — это платформа для хостинга ML-демо приложений. Более миллиона приложений уже развёрнуто на Spaces: от простых классификаторов до сложных мультимодальных систем.

Главная ценность Spaces — низкий порог входа. Вы загружаете код, платформа сама собирает окружение, устанавливает зависимости и запускает приложение. Никаких Docker-файлов, никаких конфигов nginx, никакого SSH на сервер.

Как это работает

Под капотом Spaces — это Git-репозиторий с автоматическим CI/CD:

  1. Вы создаёте Space и выбираете SDK (Gradio, Streamlit или Docker)

  2. Загружаете код через веб-интерфейс или git push

  3. Spaces автоматически читает requirements.txt и устанавливает зависимости

  4. Запускается app.py (или указанный вами файл)

  5. Приложение становится доступно по публичной ссылке

Каждый push запускает пересборку. Изменили код — через минуту изменения в продакшене.

Поддерживаемые SDK

Gradio — основной SDK для ML-демо. Лучшая интеграция с экосистемой Hugging Face.

Streamlit — альтернатива для тех, кто уже знаком со Streamlit. Полная поддержка всех фич.

Docker — для сложных приложений, которым нужен полный контроль над окружением. Можно запускать что угодно: Flask, FastAPI, Node.js, даже статические сайты.

Тарифы и ресурсы

Spaces предлагает бесплатный тир и несколько платных опций:

Тип

CPU

RAM

GPU

Цена

CPU Basic

2 vCPU

16 GB

Бесплатно

CPU Upgrade

8 vCPU

32 GB

$0.03/час

Nvidia T4 small

4 vCPU

15 GB

16 GB

$0.40/час

Nvidia T4 medium

8 vCPU

30 GB

16 GB

$0.60/час

Nvidia L4

8 vCPU

30 GB

24 GB

$0.80/час

Nvidia L40S

8 vCPU

62 GB

48 GB

$1.80/час

Nvidia A10G small

4 vCPU

15 GB

24 GB

$1.00/час

Nvidia A100 large

12 vCPU

142 GB

80 GB

$2.50/час

Для CPU-инференса квантизированных моделей бесплатного тира более чем достаточно. 16 GB RAM хватает для моделей до 7B параметров в Q4-квантизации.

ZeroGPU

Отдельно стоит упомянуть ZeroGPU — экспериментальную фичу, которая динамически выделяет GPU только на время инференса. Для пользователей с PRO-подпиской ($9/месяц) предоставляется бесплатная квота GPU-времени, остальные получают ограниченный доступ с очередью. Под капотом — Nvidia A100, одни из самых мощных GPU на рынке.

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

Особенности бесплатного тира

Бесплатные Spaces имеют несколько ограничений, о которых важно знать:

Холодный старт. После 5-15 минут бездействия Space “засыпает”. Следующий запрос его “разбудит”, но это займёт 1-3 минуты. Модель загружается заново, кэш очищается.

Непостоянный диск. Всё, что вы записываете на диск (кроме кэша моделей), теряется при перезапуске. Не храните важные данные локально.

Общие ресурсы. Бесплатные Spaces работают на shared-инфраструктуре. В моменты пиковой нагрузки производительность может падать.

Нет гарантий uptime. Это бесплатный сервис. Для production-нагрузок нужен платный тир или собственная инфраструктура.

Управление секретами

Никогда не хардкодьте API-ключи и токены в коде. Spaces поддерживает два типа переменных окружения:

Variables — для несекретных данных (имена моделей, конфигурация). Видны в настройках, копируются при дублировании Space.

Secrets — для API-ключей и токенов. Скрыты после сохранения, не копируются при дублировании.

Доступ из кода стандартный:

import os
api_key = os.getenv("MY_API_KEY")
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 4 [2]

Интеграция с Hub

Spaces тесно интегрированы с остальной экосистемой Hugging Face:

  • Модели с Hub загружаются через huggingface_hub без дополнительной авторизации

  • Можно указать связанные модели и датасеты в README — они появятся в UI

  • Spaces можно встраивать в карточки моделей и датасетов

  • ArXiv-интеграция: демо появляются на страницах научных статей

Это создаёт замкнутую экосистему: модель на Hub, датасет на Hub, демо на Spaces — всё связано и доступно в одном месте.

Почему CPU и почему это работает

Давайте сразу разберёмся с главным вопросом: как вообще можно запускать LLM на CPU?

Когда OpenAI выпустила GPT-3, для его запуска требовалось несколько сотен гигабайт видеопамяти. Модели меньшего размера тоже требовали GPU — это казалось аксиомой. Но потом появились две технологии, которые всё изменили.

Квантизация: сжимаем модель без потери смысла

Первая технология — квантизация. Идея простая: вместо того чтобы хранить веса модели в формате float16 (16 бит на каждое число), они сжимаются до 4 бит. Это как JPEG для нейросетей — качество немного падает, но размер уменьшается в 4 раза.

Почему это работает? Оказывается, большинство весов в нейросети близки к нулю или к небольшим значениям. Высокая точность для их хранения не требуется. А те веса, которые действительно важны, можно хранить с более высокой точностью — это называется смешанная квантизация.

На практике разница между оригинальной моделью и её квантизированной версией почти незаметна в обычных диалогах. Вы не отличите ответы Q4-модели от FP16-оригинала без специальных тестов.

llama.cpp: C++ магия для CPU

Вторая технология — это библиотека llama.cpp. Её создал Георги Герганов (Georgi Gerganov), и она совершила маленькую революцию в мире LLM.

llama.cpp написана на чистом C++ без зависимости от CUDA или других GPU-фреймворков. Она использует:

  • SIMD-инструкции процессора (AVX, AVX2) для параллельных вычислений

  • Оптимизированное управление памятью [4]

  • Эффективную работу с квантизированными весами

Результат: модель, которая на PyTorch требует 16 GB видеопамяти, на llama.cpp работает в 2 GB оперативки. И работает быстро — не в реальном времени, но достаточно для интерактивного использования.

Через Python-обёртку llama-cpp-python вся эта магия доступна как обычная библиотека.

Почему Hugging Face Spaces

Для хостинга используем Hugging Face Spaces — платформу, подробно описанную выше. Бесплатный CPU-тир (2 vCPU, 16 GB RAM) идеально подходит для нашей задачи: 16 гигабайт — более чем достаточно для квантизированной 3-миллиардной модели.

Выбор модели: почему Qwen2.5-3B

Выбор модели для CPU-инференса — это всегда компромисс. С одной стороны, хочется модель поумнее. С другой — она должна влезть в 16 GB RAM и генерировать ответы за разумное время.

Какие есть варианты

На момент написания статьи для CPU-инференса популярны несколько семейств моделей:

Llama 3.2 — отличные модели от Meta, но версия 3B плохо работает с русским языком. Для англоязычных проектов — отличный выбор.

Phi-3 — компактные модели от Microsoft. Phi-3 Mini (3.8B) показывает впечатляющие результаты на бенчмарках, но тоже слабо поддерживает русский.

Qwen2.5 — модели от Alibaba. Qwen2.5-3B-Instruct официально поддерживает 29+ языков, включая русский. И это не просто “поддерживает” — модель реально хорошо генерирует текст на русском.

Gemma 2 — модели от Google. Gemma 2 2B неплохо работает, но 3B версии нет.

После тестирования выбор пал на Qwen2.5-3B-Instruct по следующим причинам:

  1. Размер: 3 миллиарда параметров — оптимальный баланс для CPU. Квантизированная версия Q4_K_M занимает около 2.1 GB.

  2. Качество: Qwen2.5 показывает отличные результаты на бенчмарках, часто обходя модели аналогичного и даже большего размера.

  3. Многоязычность: Официально поддерживает 29+ языков, включая русский, английский, китайский, французский и другие. Это критично для русскоязычных пользователей.

  4. Контекст: Поддержка до 32K токенов на входе и до 8K токенов на генерацию — можно вести длинные диалоги без потери контекста.

  5. Instruct-тюнинг: Модель уже обучена следовать инструкциям и вести диалог. Не нужно изобретать свой формат промптов.

Модель доступна на Hugging Face: Qwen/Qwen2.5-3B-Instruct-GGUF [5]

Какой квант выбрать

В репозитории GGUF-версии модели есть несколько вариантов квантизации:

Вариант

Размер

Качество

Скорость

Q2_K

~1.2 GB

Низкое

Быстро

Q3_K_M

~1.6 GB

Приемлемое

Быстро

Q4_K_M

~2.1 GB

Хорошее

Средне

Q5_K_M

~2.5 GB

Очень хорошее

Медленнее

Q8_0

~3.5 GB

Почти оригинал

Медленно

Рекомендуемый вариант — Q4_K_M, это золотая середина. “K” означает k-quant — метод квантизации с переменной точностью, где более важные слои (attention, первые и последние) сжимаются меньше. “M” означает Medium — средний размер файла (есть также варианты S — Small и L — Large). Это даёт лучшее соотношение качества к размеру, чем простая Q4 квантизация.

Если у вас есть лишние гигабайты памяти, можно попробовать Q5_K_M. Если памяти впритык — Q3_K_M всё ещё даёт приемлемое качество.

Структура проекта

Проект состоит из трёх файлов:

my-ai-assistant/
├── README.md           # Конфигурация Space
├── app.py              # Основной код приложения
└── requirements.txt    # Зависимости
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 5 [2]

requirements.txt

https://huggingface.co/Luigi/llama-cpp-python-wheels-hf-spaces-free-cpu/resolve/main/llama_cpp_python-0.3.22-cp310-cp310-linux_x86_64.whl
gradio>=6.0.0
huggingface-hub>=0.20.0
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 6 [2]

Обратите внимание [6] на первую строку — это прямая ссылка на prebuilt wheel для llama-cpp-python. Почему нельзя просто написать pip install llama-cpp-python?

Проблема в том, что llama-cpp-python — это не чистый Python-пакет. Внутри него лежит вся библиотека llama.cpp, написанная на C++. При установке через pip происходит компиляция этого C++ кода, а для этого нужен компилятор (gcc/clang) и заголовочные файлы.

На Hugging Face Spaces ничего этого нет — там минимальный Docker-контейнер без средств разработки. Установка из PyPI падает с ошибкой [7] вроде:

error: command 'gcc' failed: No such file or directory
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 7 [2]

Решение — использовать prebuilt wheel. Это архив с уже скомпилированным кодом, который просто распаковывается при установке.

Как получить ссылку на wheel:

  1. Откройте репозиторий Luigi с wheel-файлами [8]

  2. Найдите файл для Python 3.10 и Linux x86_64 (например, llama_cpp_python-0.3.22-cp310-cp310-linux_x86_64.whl)

  3. Нажмите на файл, затем скопируйте прямую ссылку — она будет вида https://huggingface.co/Luigi/.../resolve/main/имя_файла.whl

  4. Вставьте эту ссылку первой строкой в requirements.txt

Расшифровка имени файла: cp310 означает CPython 3.10, linux_x86_64 — платформа.

Важно: wheel-файлы от Luigi собраны для Python 3.10. По умолчанию HF Spaces может использовать более новую версию Python, поэтому необходимо явно указать версию в конфигурации Space — иначе получите ошибку is not a supported wheel on this platform.

Спасибо пользователю Luigi за поддержку этого репозитория — он регулярно обновляет wheel-файлы под новые версии llama-cpp-python.

README.md

---
title: Qwen Chat
emoji: 🤖
colorFrom: blue
colorTo: purple
sdk: gradio
sdk_version: 6.5.1
app_file: app.py
python_version: "3.10"
pinned: false
---
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 8 [2]

Этот файл — конфигурация вашего Space. Hugging Face читает YAML-блок между --- и применяет настройки:

  • title — название, отображается в интерфейсе

  • emoji — иконка Space

  • sdk: gradio — указывает, что это Gradio-приложение

  • sdk_version — версия Gradio (опционально, но рекомендуется для воспроизводимости)

  • app_file — точка входа, по умолчанию app.py

  • python_version: "3.10"критически важно для совместимости с wheel-файлами Luigi

Без указания python_version Space может запуститься на Python 3.11+ и установка wheel упадёт с ошибкой.

app.py

Теперь самое интересное — код приложения. Полный код приведён в конце статьи в разделе Полный код для копирования [9], а здесь разберём его по частям.

Разбор кода по частям

Давайте разберём каждую часть кода подробнее.

Блок конфигурации

MODEL_REPO = "Qwen/Qwen2.5-3B-Instruct-GGUF"
MODEL_FILE = "qwen2.5-3b-instruct-q4_k_m.gguf"
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 9 [2]

Все параметры вынесены в константы в начале файла. Это не просто “хороший стиль” — это практично. Захотите попробовать другую модель? Поменяйте две строки. Нужно настроить температуру? Одна строка. Не нужно искать магические числа по всему коду.

MODEL_REPO — это идентификатор репозитория на Hugging Face в формате owner/repo-name. MODEL_FILE — имя конкретного файла для скачивания.

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

model_path = hf_hub_download(
    repo_id=MODEL_REPO,
    filename=MODEL_FILE,
)
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 10 [2]

Функция hf_hub_download из библиотеки huggingface_hub делает несколько вещей:

  1. Проверяет, есть ли файл в локальном кэше

  2. Если нет — скачивает его с Hugging Face Hub

  3. Возвращает локальный путь к файлу

При первом запуске это займёт 2-3 минуты (файл ~2.1 GB). При последующих запусках модель берётся из кэша мгновенно. Кэш хранится в ~/.cache/huggingface/hub/.

Инициализация Llama

llm = Llama(
    model_path=model_path,
    n_ctx=CONTEXT_SIZE,
    n_threads=2,
    verbose=False,
)
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 11 [2]

Создаём объект модели. Важные параметры:

  • n_ctx — размер контекста в токенах. Это сколько текста модель может “помнить” за один вызов. Системный промпт + история диалога + текущее сообщение + ответ — всё должно влезть в этот лимит.

  • n_threads=2 — количество CPU-потоков для инференса. На бесплатном тире HF Spaces ровно 2 vCPU, больше ставить бессмысленно.

  • verbose=False — отключаем дебаг-вывод. С verbose=True модель печатает кучу информации о загрузке, что засоряет логи.

Функция chat

def chat(message: str, history: list) -> str:
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 12 [2]

Это сердце приложения. Gradio вызывает эту функцию каждый раз, когда пользователь отправляет сообщение. Она получает текущее сообщение и всю историю диалога.

В Gradio 6.x история приходит в OpenAI-style формате:

[
    {"role": "user", "content": [{"type": "text", "text": "Привет"}]},
    {"role": "assistant", "content": [{"type": "text", "text": "Здравствуйте!"}]}
]
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 13 [2]

Обратите внимание: content — это список блоков контента, а не просто строка. Это позволяет передавать мультимодальный контент (текст + изображения). Для текстовых сообщений нужно извлечь текст из блоков.

Функция:

  1. Формирует список сообщений в формате OpenAI Chat API (role/content)

  2. Добавляет системный промпт в начало

  3. Извлекает текст из structured content и добавляет историю диалога

  4. Добавляет текущее сообщение пользователя

  5. Вызывает модель через create_chat_completion

  6. Извлекает и возвращает текст ответа

Gradio интерфейс

demo = gr.ChatInterface(
    fn=chat,
    title="AI-ассистент на Qwen2.5-3B",
    ...
)
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 14 [2]

Используем gr.ChatInterface — специализированный компонент для чат-ботов, описанный в разделе “Что такое Gradio”. Достаточно передать функцию chat, указать заголовок и примеры — Gradio сделает остальное.

Параметры генерации

Параметр

Значение

Описание

n_ctx

4096

Размер контекста. Больше = длиннее диалоги, но больше памяти

max_tokens

1024

Максимальная длина ответа

temperature

0.7

Креативность. 0.1 — строго по делу, 0.9 — фантазирует

top_p

0.9

Nucleus sampling. Обычно не трогают

repeat_penalty

1.1

Штраф за повторения [10]. Помогает избежать зацикливания

MAX_HISTORY

10

Лимит сообщений в истории. Предотвращает переполнение контекста

Настройка системного промпта

Системный промпт — это инструкция, которая задаёт поведение [11] модели. В данном примере он простой:

SYSTEM_PROMPT = """You are a helpful AI assistant. Respond in Russian 
if the user writes in Russian. Be concise and to the point."""
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 15 [2]

Почему системные промпты лучше писать на английском?

Большинство современных LLM (GPT, Claude, Llama, Gemini) обучались преимущественно на английских текстах. Это означает:

  1. Лучшее понимание инструкций. Модель точнее интерпретирует команды на английском — меньше двусмысленностей и ошибок в следовании указаниям.

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

  3. Консистентность поведения [12]. На английском модель ведёт себя более предсказуемо — особенно важно для сложных инструкций с условиями и ограничениями.

При этом модель отлично понимает, что отвечать нужно на русском — достаточно явно указать это в промпте (“Respond in Russian”).

Хороший системный промпт:

  • Определяет роль и экспертизу модели

  • Задаёт формат и стиль ответов

  • Указывает, как вести себя в неоднозначных ситуациях

  • Ограничивает область ответов (если нужно)

Реальные кейсы использования

Ниже приведены готовые конфигурации для типичных сценариев. Достаточно заменить SYSTEM_PROMPT в коде на один из вариантов.

Технический ассистент / Code Review Bot

Ассистент для разработчиков: отвечает на вопросы о коде, помогает с отладкой, предлагает улучшения.

SYSTEM_PROMPT = """You are an experienced senior developer with 10+ years of experience.
Your tasks:
- Answer technical programming questions
- Conduct code reviews: find bugs, suggest improvements
- Explain complex concepts in simple terms
- Provide code examples with comments

Rules:
- If a question is ambiguous, ask for context
- If you see a potential security issue, warn about it
- If you're unsure of an answer, say so honestly
- Respond in the same language the user writes in"""
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 16 [2]

Примеры использования:

  • “Проверь этот код на баги: [код]”

  • “Как оптимизировать этот SQL-запрос?”

  • “Объясни разницу между async/await и промисами”

Помощник по написанию текстов / Редактор

Ассистент для авторов: помогает улучшать тексты, исправляет ошибки, предлагает формулировки.

SYSTEM_PROMPT = """You are a professional editor and copywriter.
Your tasks:
- Fix grammatical and stylistic errors
- Improve text structure
- Suggest more precise and concise wording
- Adapt text for the target audience

Rules:
- Preserve the author's voice and style
- Explain why you suggest changes
- Offer multiple options when possible
- Don't change the meaning without explicit request
- Respond in the same language as the input text"""
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 17 [2]

Примеры использования:

  • “Отредактируй этот абзац: [текст]”

  • “Сделай этот текст более формальным”

  • “Сократи до 100 слов, сохранив суть”

Внутренний FAQ-бот / База знаний

Ассистент для ответов на типовые вопросы в рамках заданной темы.

SYSTEM_PROMPT = """You are a customer support assistant for TechCorp.
Your knowledge base includes information about:
- Company products and their features
- Pricing and plans
- Technical requirements
- Common issues and their solutions

Rules:
- Only answer questions related to company products
- If a question is outside your knowledge base, politely direct to a live agent
- Provide specific step-by-step instructions
- For technical issues, ask for product version and OS
- Respond in the same language the user writes in"""
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 18 [2]

Примеры использования:

  • “Как сбросить пароль?”

  • “Какие системные требования у продукта X?”

  • “Не работает функция Y, что делать?”

Языковой тренажёр

Ассистент для практики иностранного языка.

SYSTEM_PROMPT = """You are an English language teacher.
Your tasks:
- Conduct dialogue in English, adapting complexity to the learner's level
- Correct errors in user messages
- Explain grammar rules
- Suggest new words and expressions related to the conversation topic

Rules:
- After each user message, point out errors (if any)
- Suggest the correct version of the phrase
- Use real-life examples
- If the user writes in Russian, gently steer the conversation to English"""
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 19 [2]

Примеры использования:

  • “Let’s practice talking about travel”

  • “Explain the difference between ‘make’ and ‘do'”

  • “Correct my sentence: I goed to store yesterday”

Локальное тестирование

Прежде чем публиковать приложение на Hugging Face Spaces, рекомендуется протестировать его локально. Это позволит убедиться, что всё работает корректно, и упростит отладку.

Создание виртуального окружения

# Создание виртуального окружения
python -m venv venv

# Активация (Linux/macOS)
source venv/bin/activate

# Активация (Windows)
venvScriptsactivate
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 20 [2]

Установка зависимостей

Для локального запуска llama-cpp-python устанавливается иначе, чем на HF Spaces. Локально пакет компилируется из исходников, поэтому нужен компилятор C++.

Linux (Ubuntu/Debian):

sudo apt-get update
sudo apt-get install build-essential
pip install llama-cpp-python gradio huggingface-hub
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 21 [2]

macOS:

xcode-select --install  # если ещё не установлен
pip install llama-cpp-python gradio huggingface-hub
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 22 [2]

Windows:

Требуется Visual Studio Build Tools с компонентом “C++ build tools”.

pip install llama-cpp-python gradio huggingface-hub
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 23 [2]

Если компиляция не удаётся, можно использовать prebuilt wheels из репозитория [13].

Запуск приложения

После установки зависимостей создайте файл app.py и запустите:

python app.py
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 24 [2]

Проверка работоспособности

После запуска в консоли появится сообщение:

Running on local URL:  http://127.0.0.1:7860
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 25 [2]

Откройте эту ссылку в браузере. Появится интерфейс чата, в котором можно протестировать работу модели.

При первом запуске модель загружается из Hugging Face Hub (~2.1 GB), это занимает 2-3 минуты в зависимости от скорости интернета. Последующие запуски используют закэшированную модель и стартуют быстрее.

Различия между локальным запуском и HF Spaces

Аспект

Локально

HF Spaces

Установка llama-cpp-python

Компиляция из исходников

Prebuilt wheel

requirements.txt

Стандартные пакеты

URL на wheel-файл

Производительность

Зависит от железа

2 vCPU, 16 GB RAM

Доступ

Только локально

Публичная ссылка

Для локального тестирования requirements.txt может выглядеть проще:

llama-cpp-python
gradio>=6.0.0
huggingface-hub>=0.20.0
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 26 [2]

Но для деплоя на HF Spaces используется версия с prebuilt wheel.

Деплой на Hugging Face Spaces

Остался последний шаг — публикация. Весь процесс занимает 5 минут.

Шаг 1: Создание Space

  1. Зайдите на huggingface.co [14] и войдите в аккаунт

  2. Нажмите на аватар → New Space

  3. Заполните форму:

    • Owner: ваш username

    • Space name: например, qwen-assistant

    • License: выберите любую (MIT, Apache 2.0)

    • SDK: Gradio

    • Hardware: CPU basic (Free)

  4. Нажмите Create Space

Шаг 2: Загрузка файлов

Есть два способа:

Через веб-интерфейс (проще):

  1. На странице Space нажмите “Files” → “Add file” → “Upload files”

  2. Загрузите README.md, app.py и requirements.txt

  3. Нажмите Commit

Через Git (для тех, кто любит командную строку):

git clone https://huggingface.co/spaces/YOUR_USERNAME/qwen-assistant
cd qwen-assistant
# Скопируйте README.md, app.py и requirements.txt в эту папку
git add .
git commit -m "Initial commit"
git push
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 27 [2]

Шаг 3: Ожидание и мониторинг

После загрузки файлов Space автоматически начнёт сборку. Это можно наблюдать во вкладке “Logs”.

Что происходит:

  1. Building — установка зависимостей из requirements.txt (~1-2 минуты)

  2. Running — запуск app.py

  3. Загрузка модели из Hugging Face Hub (~2-3 минуты при первом запуске)

  4. Инициализация Llama

  5. Запуск Gradio-сервера

Общее время первого запуска: 3-5 минут. После этого Space готов к работе.

В логах вы увидите примерно такое:

Загрузка модели...
Модель загружена: /root/.cache/huggingface/hub/.../qwen2.5-3b-instruct-q4_k_m.gguf
Модель инициализирована
Running on local URL:  http://127.0.0.1:7860
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 28 [2]

Когда появится строка “Running on local URL”, Space готов. Можете открыть его по публичной ссылке вида https://huggingface.co/spaces/YOUR_USERNAME/qwen-assistant.

Типичные ошибки

Ошибки и их решения

Ошибка

Причина

Решение

is not a supported wheel on this platform

Несовместимая версия Python

Добавьте python_version: "3.10" в README.md

ModuleNotFoundError: llama_cpp

Неправильный wheel-файл

Проверьте URL в requirements.txt

OutOfMemoryError

Модель слишком большая

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

FileNotFoundError

Опечатка в имени файла модели

Проверьте MODEL_FILE

Space “Building” бесконечно

Ошибка в коде

Смотрите логи во вкладке Logs

Очень медленная генерация

Первый запуск

Подождите, модель кэшируется

Про холодный старт

Важный нюанс: бесплатные Spaces “засыпают” после нескольких минут бездействия (обычно 5-15 минут без запросов). При следующем обращении происходит холодный старт — Space просыпается, и модель загружается заново.

Это занимает 2-3 минуты. Первый пользователь после простоя видит спиннер и ждёт.

Есть несколько способов борьбы с этим:

Keep-alive пинги. Простой скрипт, который каждые 5 минут делает запрос к вашему Space. Можно запустить на бесплатном сервере (GitHub Actions, бесплатный VPS) или даже локально.

Платный тир. CPU Upgrade стоит 0.03/час (~22/месяц при 24/7), но Space не засыпает и работает постоянно.

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

Безопасность и ограничения

Несколько вещей, о которых стоит помнить:

Модель не идеальна. Qwen2.5-3B — это маленькая модель. Она может ошибаться, галлюцинировать, давать неправильные ответы. Не используйте её для критически важных решений без проверки.

Нет фильтрации контента. В отличие от ChatGPT, у локальной модели нет встроенных guardrails. Она может генерировать нежелательный контент, если пользователь попросит. Для публичного сервиса стоит добавить фильтрацию.

Логи видны вам. Все запросы к вашему Space логируются. Если вы делаете публичный сервис, предупредите пользователей о сборе данных.

Диск не persistent. Всё, что Space записывает на диск (кроме кэша моделей), теряется при перезапуске. Не храните важные данные локально.

Скорость генерации и оптимизация

Поговорим о скорости. CPU — это не GPU, и чудес ждать не стоит.

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

Платформа

CPU

Скорость

Короткий ответ (50 токенов)

Средний ответ (200 токенов)

HF Spaces Free

2 vCPU

3-7 токен/с

8-17 сек

30-70 сек

MacBook M1/M2

8 cores

12-18 токен/с

3-5 сек

12-18 сек

Intel i7 (12th gen)

12 cores

8-12 токен/с

5-7 сек

18-25 сек

AMD Ryzen 7 5800X

8 cores

10-14 токен/с

4-5 сек

15-20 сек

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

На бесплатном тире HF Spaces (2 vCPU) Qwen2.5-3B-Q4_K_M генерирует примерно 3-7 токенов в секунду. Это значит:

  • Короткий ответ (50 токенов) — 8-17 секунд

  • Средний ответ (200 токенов) — 30-70 секунд

  • Длинный ответ (500 токенов) — 70-170 секунд

Для интерактивного чата это терпимо. Для production-нагрузки с множеством пользователей — нет.

Как ускорить

Уменьшить max_tokens. Если вам не нужны длинные ответы, ограничьте их. max_tokens=256 вместо max_tokens=1024 сократит время ожидания в 4 раза.

Использовать streaming. Вместо ожидания полного ответа можно выводить токены по мере генерации. Пользователь видит, что что-то происходит, и не уходит. Для этого нужно немного изменить код:

def chat(message: str, history: list):
    messages = [{"role": "system", "content": SYSTEM_PROMPT}]
    
    # Gradio 6.x: извлекаем текст из structured content
    for msg in history:
        content = msg["content"]
        if isinstance(content, list):
            text = "".join(
                block.get("text", "") for block in content 
                if block.get("type") == "text"
            )
        else:
            text = content
        messages.append({"role": msg["role"], "content": text})
    
    messages.append({"role": "user", "content": message})
    
    response = llm.create_chat_completion(
        messages=messages,
        stream=True,  # Включаем streaming
    )
    
    partial_message = ""
    for chunk in response:
        delta = chunk["choices"][0]["delta"]
        if "content" in delta:
            partial_message += delta["content"]
            yield partial_message  # Возвращаем частичный ответ
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 30 [2]

И в Gradio-интерфейсе ничего менять не нужно — ChatInterface автоматически поддерживает генераторы.

Перейти на платный тир. CPU Upgrade ($0.03/час) даёт 8 vCPU и 32 GB RAM. Это увеличит скорость примерно вдвое и позволит использовать модели побольше.

Использовать GPU-тир. Если скорость критична, ZeroGPU на HF Spaces даёт ~30-50 токенов в секунду. PRO-подписчики получают бесплатную квоту GPU-времени, для остальных доступ ограничен.

Полный код для копирования

Ниже приведён полный код проекта, готовый для копирования и использования.

README.md

---
title: Qwen Chat
emoji: 🤖
colorFrom: blue
colorTo: purple
sdk: gradio
sdk_version: 6.5.1
app_file: app.py
python_version: "3.10"
pinned: false
---
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 31 [2]

requirements.txt

https://huggingface.co/Luigi/llama-cpp-python-wheels-hf-spaces-free-cpu/resolve/main/llama_cpp_python-0.3.22-cp310-cp310-linux_x86_64.whl
gradio>=6.0.0
huggingface-hub>=0.20.0
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 32 [2]

app.py

import gradio as gr
from llama_cpp import Llama
from huggingface_hub import hf_hub_download
import traceback

# =============================================================================
# КОНФИГУРАЦИЯ
# =============================================================================

MODEL_REPO = "Qwen/Qwen2.5-3B-Instruct-GGUF"
MODEL_FILE = "qwen2.5-3b-instruct-q4_k_m.gguf"

CONTEXT_SIZE = 4096
MAX_TOKENS = 1024
TEMPERATURE = 0.7
TOP_P = 0.9
REPEAT_PENALTY = 1.1
MAX_HISTORY = 10  # Максимум сообщений в истории

SYSTEM_PROMPT = """You are a helpful AI assistant. Respond in Russian 
if the user writes in Russian. Be concise and to the point."""

# =============================================================================
# ЗАГРУЗКА МОДЕЛИ
# =============================================================================

try:
    print("Загрузка модели...")
    print("Это займёт 2-3 минуты при первом запуске...")
    
    model_path = hf_hub_download(
        repo_id=MODEL_REPO,
        filename=MODEL_FILE,
    )
    print(f"[OK] Модель загружена: {model_path}")

    print("Инициализация модели...")
    llm = Llama(
        model_path=model_path,
        n_ctx=CONTEXT_SIZE,
        n_threads=2,
        verbose=False,
    )
    print("[OK] Модель готова к работе!")

except Exception as e:
    print(f"[ERROR] Ошибка при загрузке модели: {e}")
    traceback.print_exc()
    raise

# =============================================================================
# ФУНКЦИЯ ЧАТА
# =============================================================================

def chat(message: str, history: list) -> str:
    try:
        messages = [{"role": "system", "content": SYSTEM_PROMPT}]
        
        # Ограничиваем историю последними N сообщениями
        recent_history = history[-MAX_HISTORY:] if len(history) > MAX_HISTORY else history
        
        # Gradio 6.x: история в OpenAI-style формате
        for msg in recent_history:
            role = msg["role"]
            content = msg["content"]
            if isinstance(content, list):
                text = "".join(
                    block.get("text", "") for block in content 
                    if block.get("type") == "text"
                )
            else:
                text = content
            messages.append({"role": role, "content": text})
        
        messages.append({"role": "user", "content": message})
        
        response = llm.create_chat_completion(
            messages=messages,
            max_tokens=MAX_TOKENS,
            temperature=TEMPERATURE,
            top_p=TOP_P,
            repeat_penalty=REPEAT_PENALTY,
            stream=False,
        )
        
        return response["choices"][0]["message"]["content"]
    
    except Exception as e:
        print(f"[ERROR] Произошла ошибка: {str(e)}")
        traceback.print_exc()
        return "Извините, произошла ошибка. Попробуйте переформулировать вопрос."

# =============================================================================
# GRADIO ИНТЕРФЕЙС
# =============================================================================

demo = gr.ChatInterface(
    fn=chat,
    title="AI-ассистент на Qwen2.5-3B",
    description="Бесплатный AI-ассистент, работающий на CPU. Поддерживает русский язык.",
    examples=[
        "Привет! Расскажи о себе.",
        "Напиши короткое стихотворение о программировании.",
        "Объясни, что такое машинное обучение, простыми словами.",
    ],
)

if __name__ == "__main__":
    demo.launch()
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 33 [2]

Инструкция по использованию

  1. Создайте папку проекта и поместите в неё все три файла (README.md, app.py, requirements.txt)

  2. Для деплоя на HF Spaces: загрузите файлы в новый Space (SDK: Gradio, Hardware: CPU basic)

  3. Для локального запуска: установите зависимости через pip install llama-cpp-python gradio huggingface-hub и выполните python app.py

Итого

Вот что получилось:

  • Модель: Qwen2.5-3B-Instruct (Q4_K_M квантизация)

  • Интерфейс: Gradio ChatInterface

  • Хостинг: Hugging Face Spaces (бесплатный CPU)

  • Языки: Русский, английский и ещё 27+

  • Код: ~70 строк Python

Весь проект состоит из трёх файлов и разворачивается за 15-20 минут. Никаких GPU, никаких платежей, никакой сложной инфраструктуры.

Итоговая конфигурация

Параметр

Значение

Модель

Qwen2.5-3B-Instruct-GGUF

Квантизация

Q4_K_M (~2.1 GB)

Контекст

4096 токенов

Скорость

~3-7 токенов/сек

Стоимость

Бесплатно

Время деплоя

~5 минут (первый запуск)

Когда это подходит

Бесплатный CPU-тир идеален для:

  • Личных проектов и экспериментов

  • Демонстраций и прототипов

  • Обучения и изучения LLM

  • Небольших внутренних инструментов

Не подходит для:

  • Production с высокой нагрузкой

  • Приложений, где критична скорость отклика

  • Множества одновременных пользователей

Что дальше

Если хочется развить проект, вот несколько направлений:

RAG (Retrieval-Augmented Generation) — добавить поиск по вашим документам. Модель будет отвечать на вопросы, используя информацию из ваших файлов. Это превращает простого чат-бота в ассистента по документации.

Function calling — научить бота вызывать внешние API. Например, искать в интернете, проверять погоду, управлять умным домом. Qwen2.5 поддерживает function calling из коробки.

Qwen2.5-7B — перейти на бОльшую модель. 7B-версия умнее, квантизированная Q4_K_M занимает ~4.5 GB. Технически влезает в 16 GB, но для комфортной работы с длинным контекстом лучше иметь 32 GB — платный тир или свой сервер.

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

Gradio Blocks — если ChatInterface слишком простой, можно использовать gr.Blocks для создания более сложного UI с дополнительными контролами.

FAQ

Можно ли использовать в production?

Бесплатный CPU-тир не подходит для production с высокой нагрузкой. Основные ограничения: низкая скорость генерации (3-7 токенов/сек), засыпание Space после простоя, отсутствие гарантий доступности. Для production рекомендуется CPU Upgrade ($0.03/час за 8 vCPU, 32 GB RAM) или собственный сервер.

Как использовать другую модель?

Достаточно изменить две константы в начале файла:

  • MODEL_REPO — репозиторий на Hugging Face (например, "TheBloke/Llama-2-7B-Chat-GGUF")

  • MODEL_FILE — имя GGUF-файла из репозитория

Убедитесь, что модель влезает в 16 GB RAM (для Q4-квантизации это модели до ~7B параметров).

Почему Space засыпает и как с этим бороться?

Бесплатные Spaces засыпают после 5-15 минут бездействия для экономии ресурсов. Варианты решения:

  • Keep-alive пинги через GitHub Actions или cron-задачу

  • CPU Upgrade (0.03/час, ~22/мес при 24/7) — Space работает постоянно

  • Принять как данность для личных проектов

Можно ли запустить на Windows/Mac локально?

Да. Установка llama-cpp-python требует компиляции C++ кода, но для большинства платформ есть готовые wheels.

Вариант 1: CPU-версия (рекомендуется для начала)

pip install llama-cpp-python gradio huggingface-hub
Запускаем AI-ассистента на бесплатном CPU: Qwen2.5 + Gradio + Hugging Face Spaces - 35 [2]

На стандартных платформах (Windows x64, macOS, Linux x86_64) pip автоматически скачает prebuilt wheel.

Вариант 2: С GPU-ускорением

Вариант 3: Сборка из исходников

Если prebuilt wheel недоступен, установите компилятор:

  • Windows: Visual Studio Build Tools

  • macOS: xcode-select --install

  • Linux: sudo apt install build-essential

Затем: pip install llama-cpp-python --no-binary llama-cpp-python.

Как добавить RAG (поиск по документам)?

Базовый RAG требует:

  1. Библиотеку для эмбеддингов (например, sentence-transformers)

  2. Векторную базу данных (например, chromadb или faiss)

  3. Логику поиска релевантных фрагментов и добавления их в контекст

Это тема для отдельной статьи, но Qwen2.5 хорошо работает с RAG благодаря поддержке длинного контекста.

Сколько пользователей может обслуживать бесплатный тир?

Реалистично — 1-2 одновременных пользователя. Генерация ответа занимает 10-60 секунд, в это время другие запросы ждут в очереди. Для множества пользователей нужен платный тир или несколько Space с балансировкой.

Как увеличить скорость генерации?

  • Уменьшить max_tokens (256 вместо 1024)

  • Использовать более агрессивную квантизацию (Q3_K_M вместо Q4_K_M)

  • Перейти на платный CPU-тир (8 vCPU даёт ~2x ускорение)

  • Использовать GPU-тир (T4 даёт ~5-10x ускорение)

  • Включить streaming для лучшего UX (пользователь видит ответ по мере генерации)

Ссылки

Автор: Rummar

Источник [20]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/25260

URLs in this post:

[1] обучения: http://www.braintools.ru/article/5125

[2] Image: https://sourcecraft.dev/

[3] логикой: http://www.braintools.ru/article/7640

[4] памятью: http://www.braintools.ru/article/4140

[5] Qwen/Qwen2.5-3B-Instruct-GGUF: https://huggingface.co/Qwen/Qwen2.5-3B-Instruct-GGUF

[6] внимание: http://www.braintools.ru/article/7595

[7] ошибкой: http://www.braintools.ru/article/4192

[8] репозиторий Luigi с wheel-файлами: https://huggingface.co/Luigi/llama-cpp-python-wheels-hf-spaces-free-cpu/tree/main

[9] Полный код для копирования: #%D0%BF%D0%BE%D0%BB%D0%BD%D1%8B%D0%B9-%D0%BA%D0%BE%D0%B4-%D0%B4%D0%BB%D1%8F-%D0%BA%D0%BE%D0%BF%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F

[10] повторения: http://www.braintools.ru/article/4012

[11] поведение: http://www.braintools.ru/article/9372

[12] поведения: http://www.braintools.ru/article/5593

[13] репозитория: https://github.com/abetlen/llama-cpp-python/releases

[14] huggingface.co: https://huggingface.co

[15] jllllll/llama-cpp-python-cuBLAS-wheels: https://github.com/jllllll/llama-cpp-python-cuBLAS-wheels

[16] llama-cpp-python wheels: https://huggingface.co/Luigi/llama-cpp-python-wheels-hf-spaces-free-cpu

[17] Gradio Documentation: https://www.gradio.app/docs/

[18] Hugging Face Spaces: https://huggingface.co/docs/hub/spaces-overview

[19] llama.cpp: https://github.com/ggerganov/llama.cpp

[20] Источник: https://habr.com/ru/articles/993312/?utm_campaign=993312&utm_source=habrahabr&utm_medium=rss

www.BrainTools.ru

Rambler's Top100