Во многих туториалах по LLM всё начинается с API-ключей, платных токенов и облачных сервисов. Это рабочий путь, но для первого знакомства он не самый удобный: нужно регистрироваться, разбираться с биллингом и постоянно помнить, что каждый эксперимент что-то стоит.

Здесь пойдём проще. В этой серии мы соберём маленький LLM-чат на Python, который сначала будет работать локально: модель запускается через Ollama, а Python-код общается с ней через LiteLLM.

Это хороший стартовый маршрут по трём причинам:

  • не нужны API-ключи;

  • не нужен интернет для каждого запроса;

  • вы сразу видите, как LLM становится частью обычной Python-программы.

В первой части мы не будем строить полноценный чат. Наша задача скромнее и важнее: поднять локальную модель, подключить её к Python и получить первый осмысленный ответ из своего кода.


Серия статей

  • Часть 1. Ставим окружение и пишем первый запрос ← вы здесь

  • Часть 2. Делаем маленький консольный чат

  • Часть 3. Разбираем структуру ответа и метаданные

  • Часть 4. Добавляем историю сообщений и контекст

  • Часть 5. Ошибки и таймауты: делаем код устойчивее

  • Часть 6. Что дальше: локальные и облачные модели, развитие проекта


Что сделаем в этой части

В этой статье мы:

  • установим Ollama;

  • скачаем локальную модель;

  • проверим, что она отвечает прямо в терминале;

  • создадим чистое Python-окружение;

  • установим LiteLLM;

  • напишем первый main.py, который отправляет запрос локальной модели.


Почему для старта удобно идти локально

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

ваш Python-код → LiteLLM → Ollama → локальная модель → ответ

Это не "магия AI", а обычный программный поток.
Ваш скрипт формирует запрос, LiteLLM отправляет его в Ollama, Ollama передаёт его модели, а потом ответ возвращается обратно в код.

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


Где здесь Ollama, а где LiteLLM

На старте эти инструменты легко перепутать, поэтому сразу разделим роли.

Ollama — это инструмент, который запускает локальные модели и даёт к ним удобный доступ.

LiteLLM — это Python-библиотека, которая позволяет вызывать модель через единый интерфейс. Сегодня мы идём в локальную модель через Ollama, а позже ту же общую логику можно будет перенести и на облачные провайдеры с минимальными изменениями.

То есть роли такие:

  • Ollama поднимает локальную модель;

  • LiteLLM помогает обратиться к ней из Python;

  • наш код собирает вокруг этого приложение.


Шаг 1. Устанавливаем Ollama

Перейдите на сайт Ollama и скачайте установщик под свою систему.

  • Windows — установщик .exe

  • macOS.dmg

  • Linux — команда установки с сайта

После установки проверьте, что всё прошло нормально:

ollama --version

Если в ответ вы видите номер версии, значит Ollama установлена.

На Windows после запуска Ollama обычно появляется значок ? в системном трее. Это хороший признак: программа работает в фоне и готова принимать запросы.


Шаг 2. Скачиваем первую модель

Сама Ollama — это ещё не модель, а оболочка для работы с моделями. Теперь нужно скачать конкретную LLM.

Для этой серии возьмём:

ollama run qwen2.5:3b

Почему именно qwen2.5:3b:

  • это сравнительно компактная модель;

  • она обычно неплохо работает на обычных ноутбуках;

  • у неё хороший компромисс между качеством, размером и удобством старта;

  • она нормально справляется с русским языком.

При первом запуске начнётся загрузка модели. Это разовая операция: модель скачается на диск и потом будет запускаться локально.

Когда загрузка завершится, у вас откроется простой интерфейс прямо в терминале. Напишите что-нибудь по-русски, например:

Привет! Расскажи в двух предложениях, что такое Python.

Если модель отвечает — отлично. Значит, самый важный технический барьер уже пройден: локальная LLM у вас работает.

Чтобы выйти из режима чата Ollama, используйте:

/bye

Если компьютер слабый

Если у вас немного оперативной памяти или модель работает слишком тяжело, попробуйте более лёгкий вариант:

ollama run qwen2.5:1.5b

Логика Python-кода дальше останется такой же. Поменяется только имя модели.


Шаг 3. Готовим Python-окружение

Теперь подключим Python к уже работающей локальной модели.

Создайте папку проекта и перейдите в неё:

mkdir llm-chat
cd llm-chat

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

python -m venv venv

Активируйте его.

Windows:

venv\Scripts\activate

macOS / Linux:

source venv/bin/activate

Если всё прошло нормально, в начале строки терминала появится префикс (venv).

Теперь установим LiteLLM:

pip install litellm

На этом этапе у нас уже есть всё необходимое:

  • локальная модель через Ollama;

  • Python-проект;

  • отдельное окружение;

  • библиотека для вызова модели из кода.


Шаг 4. Пишем первый main.py

Создайте файл main.py и вставьте в него код:

from litellm import completion
 
MODEL = "ollama_chat/qwen2.5:3b"
API_BASE = "http://localhost:11434"
 
 
def ask(question: str) -> str:
    response = completion(
        model=MODEL,
        messages=[
            {"role": "user", "content": question}
        ],
        api_base=API_BASE,
        request_timeout=120,
    )
    return response.choices[0].message.content
 
 
answer = ask("Привет! Напиши одно короткое предложение о Python.")
print(answer)

Теперь запустите:

python main.py

Если в консоли появился осмысленный ответ на русском языке — всё работает как надо.

И это уже важный момент: теперь модель живёт не отдельно в терминале Ollama, а встроена в ваш Python-код.


Разберём код

Здесь нет ничего лишнего — только минимальное ядро будущего приложения.

from litellm import completion

Импортируем функцию, которая делает вызов модели.

MODEL = "ollama_chat/qwen2.5:3b"

Здесь мы указываем, какую модель хотим использовать.
Префикс ollama_chat/ подсказывает LiteLLM, что запрос нужно отправить именно в Ollama.

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

MODEL = "ollama_chat/qwen2.5:1.5b"

API_BASE = "http://localhost:11434"

Это локальный адрес, по которому Ollama принимает запросы.
По умолчанию Ollama работает именно на этом порту.

messages=[{"role": "user", "content": question}]

Это уже очень важная часть.

Большинство современных LLM API работают не с одной строкой текста, а со списком сообщений. Даже если у нас пока только один вопрос, он всё равно передаётся в виде структуры с ролями.

Сейчас в этом списке всего одно сообщение:

  • role="user" — это вопрос пользователя;

  • content=question — сам текст вопроса.

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

response.choices[0].message.content

Из полного объекта ответа мы достаём только текст, который сгенерировала модель.

Пока нам этого достаточно. В следующих частях мы разберём, что ещё приходит в ответе, кроме самого текста.


Что у нас получилось

На этом этапе у нас уже есть:

  • установленная Ollama;

  • скачанная локальная модель;

  • рабочее Python-окружение;

  • установленный LiteLLM;

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

То есть теперь локальная LLM — это не абстрактная технология "где-то там", а компонент вашей программы, к которому можно обращаться из Python.

Это и есть главное достижение первой части.


Частые проблемы на этом этапе

Проблема 1. Connection refused или Failed to connect

Почему возникает: Ollama не запущена.

Что проверить: убедитесь, что Ollama действительно работает. На Windows проверьте значок ? в трее. Также можно выполнить:

ollama list

Если команда отвечает, значит сервис доступен.


Проблема 2. Model not found

Почему возникает: модель не скачана или её имя в коде не совпадает с установленной.

Что сделать: посмотрите список моделей:

ollama list

И затем убедитесь, что в коде указано точное имя модели.


Проблема 3. Ответ генерируется слишком долго

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

Что сделать: сначала просто подождите дольше, закройте тяжёлые программы, попробуйте модель полегче — например qwen2.5:1.5b.


Проблема 4. ModuleNotFoundError: No module named 'litellm'

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

Что проверить: перед запуском убедитесь, что окружение активировано и в терминале есть (venv).


Проблема 5. В PowerShell отображаются "кракозябры"

Иногда это связано с кодировкой терминала. Попробуйте выполнить:

$OutputEncoding = [System.Text.Encoding]::UTF8

А затем снова запустить скрипт.


Вывод

В этой части мы сделали самый важный первый шаг: связали локальную модель и Python-код.

Пока это ещё не чат. Наш скрипт просто отправляет один вопрос и получает один ответ. Но это уже не игрушка и не теория: у нас есть рабочее ядро будущего приложения.

Именно с этого момента LLM перестаёт быть "чем-то из чужих демо" и становится частью вашей программы.


Что дальше

Сейчас у нас есть один запрос и один ответ. Это хороший старт, но полноценного общения ещё нет.

В следующей части превратим этот минимальный пример в маленький консольный чат:

  • добавим цикл общения;

  • будем принимать вопросы от пользователя в реальном времени;

  • введём команду выхода;

  • подготовим основу для дальнейшего добавления памяти и контекста.


Продолжение

Это первая часть практического цикла по созданию небольшого LLM-приложения на Python.
Дальше - >

Комментарии (16)


  1. ErshoffPeter
    19.03.2026 11:26

    Начало уже многообещающее!

    Не останавливайтесь!


    1. kuz1 Автор
      19.03.2026 11:26

      Спасибо! За мотивацию!)


  1. Moog_Prodigy
    19.03.2026 11:26

    Не совсем понятно для чего нужна именно liteLLM , если есть стандартный requests, и код на питоне при работе с ним будет фактически такой же? Плюс requests это не только для работы с llm-ами, но и другими нейронками типа ace step, stable diffusion...


    1. kuz1 Автор
      19.03.2026 11:26

      requests — это просто транспортный слой HTTP.
      LiteLLM — это унифицированный слой именно для LLM-провайдеров.

      Через requests можно вызвать что угодно, но всю специфику разных LLM API вы обрабатываете сами.
      Через LiteLLM вы платите зависимостью, но получаете единый интерфейс, единый формат ответов и более лёгкое переключение между моделями и провайдерами.


      1. Moog_Prodigy
        19.03.2026 11:26

        Хотелось бы в следующей статье увидеть примеры этого :) Потому что переключение между моделями и провайдерами обычно заключается в изменении начальных переменных, иногда точки входа API, да...и всё по сути. Что с облачным, что с локальным - одинаково работает. А по сути это перекидывание json запросов, что так, что эдак. У вас тоже надо инициализировать API, чтобы она ответила. Почти так же как это делает requests. Вот и хочется примеров. Вдруг и правда лучше )


        1. kuz1 Автор
          19.03.2026 11:26

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


  1. WhiteBehemoth
    19.03.2026 11:26

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

    Olama - обёртка над llama.cpp

    LiteLLM - обёртка над Open AI запросами

    llama.cpp ставится не сложнее оламы. Open AI spec в простых случаях - тоже не китайская грамота. Понятно, что каждого джежая свой путь обучения, но не слишком ли упрощаете?


    1. kuz1 Автор
      19.03.2026 11:26

      Упрощаю осознанно. Цель серии — не объяснить стек до уровня llama.cpp, а показать рабочую механику LLM-интеграции на Python человеку, который раньше с этим не работал. Ollama как обёртка над llama.cpp и LiteLLM как обёртка над OpenAI spec — это честное описание. Если читатель дойдёт до конца серии и захочет глубже — у него уже будет рабочий контекст, в котором это понимание ляжет. Каждый джедай свой путь, согласен.


      1. WhiteBehemoth
        19.03.2026 11:26

        У вас подача материала хорошая, учительская. Если бы вы так рассказали про llama.cpp... Просто обёртки не только упрощают, но и ограничивают.
        Например ollama list Это, конечно, просто, но скрывает такой важный параметр как квантование моделей и размер контекста. Вы говорите в статье "если модель тормозит, выберите поменьше". Но ведь память ест не только сама модель, но и окно контекста. Тогда становится понятнее, почему при свободной видео памяти 8 GB модель 7.5 GB "не влезает".
        Я, погружаясь в тему с полного нуля полтора месяца назад, благодаря вот этому комментарию https://habr.com/ru/articles/991560/#comment_29467748 (думаю, что) сэкономил кучу времени на понимании принципов локальной LLM. Да, может чуть непонятнее в начале, но и Hugging Face и Llama.cpp - весьма дружественные к новичкам (особенно когда есть под рукой ИИ чат какой-нить).


        1. Moog_Prodigy
          19.03.2026 11:26

          Там еще есть ключик --keepalive про который в интернетах вообще сложно найти инфу, хотя ничего секретного нету. И в мелочах скрыты многие приколы. Конкретно этот ключик задает время удержания модели в памяти с последнего обращения. Меня сильно бесило, что по дефолту там 15 минут моделька висит, а потом выгружается, моделька может быть не то чтобы на hdd а даже на внешней флешке, с которой она грузиться будет полчаса. Там еще ключики всякие веселые есть, но имхо, оллама последнее время пошла куда-то не туда.


        1. Incognito4pda
          19.03.2026 11:26

          Тоже перешёл на llama.cpp + llama-swap т.к. ollama уже давно скатился в какое-то полу коммерческое дно. Да и по скорости генераций llama.cpp обходит ollama на целую голову - а это, на секундочку ключевой фактор в подобной деятельности.

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


          1. WhiteBehemoth
            19.03.2026 11:26

            а зачем llama-swap, если только llama.cpp ?


  1. Wid07
    19.03.2026 11:26

    Запускаю файл. python main.py и ничего не происходит


  1. aladkoi
    19.03.2026 11:26

    Если хочется "убить" время, делайте, как написано в статье, все равно не получите никакого адекватного результата. Для более менее "нормального" общения с моделью нужен GPU ускоритель на 16 гиг и модель не хуже qwen3 и то - это на уровне "поиграться". Локальные модели обычно ставят под эмбидинги и reranker для rag систем. Для анализа информации и работы с инструментами нужна нормальная облачная модель. Локальные модели , если у Вас только не своя минифабрика с GPU ускорителями, на уровне облачных моделей работать не будут, таковое на сегодня развитие технологий.


    1. WhiteBehemoth
      19.03.2026 11:26

      кстати да. Это ОЧЕНЬ важный момент, обойдённый автором. Если нету GPU (желательно от NVidia) то локальная LLM это грустно, медленно и малоинтересно.
      16GB это очень хорошо, но сейчас и в более популярные 8GB можно поместить не сильно обрезанную (4 бита) qwen 3.5. (модель 5,6 gb + 0.9 gb на распознавание картинок, еще и на 8к+ токенов контекстного окна останется).
      Это вполне себе интересный собеседник, да еще и без цензуры, спрашивай о чем хочешь.
      если что, краткая инструкция (если вдруг у кого возникнет желание проверить, а лламы еще нету)

      1. Скачать llama.cpp под свою видео карту (или cpu, но это грустно) https://github.com/ggml-org/llama.cpp/releases

      2. Скачать модель https://huggingface.co/HauhauCS/Qwen3.5-9B-Uncensored-HauhauCS-Aggressive/blob/main/Qwen3.5-9B-Uncensored-HauhauCS-Aggressive-Q4_K_M.gguf

      3. (опционально) модуль для распознавания картинок https://huggingface.co/HauhauCS/Qwen3.5-9B-Uncensored-HauhauCS-Aggressive/blob/main/mmproj-Qwen3.5-9B-Uncensored-HauhauCS-Aggressive-BF16.gguf

      4. Запустить сервер llama-server.exe --model [путь до модели] --mmproj [путь до модуля] Остальные параметры можно попробовать по умолчанию - в последних релизах уже и окно контекста можно не указывать - обрежется по имеющийся памяти.

      5. Открыть WebUI localhost:8080


  1. thunderspb
    19.03.2026 11:26

    А подскажите, какая самая легковесная модель? Врядли такие есть, но чтобы влезла в vps 2cpu, 2gb :) "разум " не нужен, скорость посути тоже особо.чисто приркутить к телеграм боту, чтобы он, например на основе базовых входных данных, типа погодных, писал чтото вроде "сегодня пасмурно/ясно/дождь, температура от хх до хх, ветер блабла и т.п" я чисто экспериментирую для себя.