Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Локальный запуск LLM
local_llm

Локальный запуск LLM

Запуск моделей локально: Ollama, LM Studio, llama.cpp, vLLM, требования к железу

Локальный запуск LLM

Ollama, LM Studio, llama.cpp, vLLM — выбор инструмента для локальной разработки и production

#Введение

Локальный запуск LLM позволяет запускать языковые модели на собственном железе без зависимости от облачных API. Это даёт:

  • Приватность: данные не покидают вашу инфраструктуру
  • Cost control: нет оплаты за токены
  • Customization: полный контроль над моделью
  • Offline работа: не требуется интернет

Инструменты:

ИнструментНазначениеСложность
OllamaБыстрый старт, CLI + APIНизкая
LM StudioGUI для разработкиНизкая
llama.cppCPU inference, embeddingСредняя
vLLMProduction servingВысокая

#1. Ollama

Ollama — самый простой способ запустить LLM локально. Автоматически скачивает модели, предоставляет REST API и CLI.

#Установка

# macOS brew install ollama # Linux curl -fsSL https://ollama.ai/install.sh | sh # Windows # Скачать с https://ollama.ai/download

#Запуск моделей

# Запуск модели (автоматическая загрузка) ollama run llama3.1 # Доступные команды в CLI >>> /help # справка >>> /set parameter temperature 0.8 >>> /set system Ты — помощник для Python разработчиков >>> /bye # выход # Список загруженных моделей ollama list # Удаление модели ollama rm llama3.1 # Копирование модели ollama cp llama3.1 my-llama3.1

#Модели в Ollama

# Llama 3.1 (Meta) ollama run llama3.1 # 8B ollama run llama3.1:70b # 70B # Mistral ollama run mistral # 7B ollama run mistral-nemo # 12B # Gemma (Google) ollama run gemma2 # 9B ollama run gemma2:27b # 27B # Code модели ollama run codellama # Code Llama ollama run deepseek-coder # DeepSeek Coder # Специализированные ollama run llava # Vision (image + text) ollama run nomic-embed-text # Embeddings

#Python клиент

import ollama # Простой запрос response = ollama.chat( model='llama3.1', messages=[{ 'role': 'user', 'content': 'Напиши функцию на Python для сортировки списка' }] ) print(response['message']['content']) # Streaming stream = ollama.chat( model='llama3.1', messages=[{'role': 'user', 'content': 'Расскажи о Python'}], stream=True ) for chunk in stream: print(chunk['message']['content'], end='', flush=True)

#Ollama REST API

# Запуск сервера ollama serve # API доступен на http://localhost:11434
import requests # Генерация response = requests.post( 'http://localhost:11434/api/generate', json={ 'model': 'llama3.1', 'prompt': 'Напиши hello world на Python', 'stream': False } ) print(response.json()['response']) # Chat API (OpenAI-compatible) response = requests.post( 'http://localhost:11434/api/chat', json={ 'model': 'llama3.1', 'messages': [ {'role': 'user', 'content': 'Привет!'} ], 'stream': False } ) print(response.json()['message']['content'])

#Кастомные модели (Modelfile)

# Создание Modelfile cat > Modelfile << EOF FROM llama3.1 # System prompt SYSTEM """ Ты — опытный Python разработчик. Отвечай кратко, с примерами кода. Используй best practices и type hints. """ # Параметры PARAMETER temperature 0.2 PARAMETER top_p 0.9 # Embeddings для контекста PARAMETER num_ctx 4096 EOF # Создание кастомной модели ollama create python-assistant -f Modelfile # Использование ollama run python-assistant "Как создать декоратор?"

#Ollama с LangChain

from langchain_community.chat_models import ChatOllama from langchain_core.messages import HumanMessage llm = ChatOllama( model="llama3.1", temperature=0.2, base_url="http://localhost:11434" ) response = llm.invoke([HumanMessage(content="Напиши функцию factorial")]) print(response.content) # Streaming for chunk in llm.stream([HumanMessage(content="Объясни OOP")]): print(chunk.content, end='')

#2. LM Studio

LM Studio — GUI приложение для локальных LLM. Удобно для разработки и тестирования.

#Установка и использование

1. Скачать с https://lmstudio.ai/
2. Установить и запустить
3. Search models → выбрать модель (Llama, Mistral, etc.)
4. Выбрать quantization (Q4_K_M recommended)
5. Download
6. Chat interface готова

#Features

  • Search & Download: встроенный каталог моделей HuggingFace
  • Chat Interface: удобный UI для тестирования
  • Preset Management: сохранение настроек для разных задач
  • API Server: OpenAI-compatible API

#Локальный API сервер

# LM Studio запускает локальный сервер # http://localhost:1234/v1 from openai import OpenAI client = OpenAI( base_url="http://localhost:1234/v1", api_key="not-needed" # не требуется ) response = client.chat.completions.create( model="local-model", # имя загруженной модели messages=[ {"role": "system", "content": "Ты — Python помощник"}, {"role": "user", "content": "Напиши quicksort"} ], temperature=0.2 ) print(response.choices[0].message.content)

#3. llama.cpp

llama.cpp — C++ реализация LLM inference с поддержкой GGUF. Максимальная эффективность на CPU.

#Установка

git clone https://github.com/ggerganov/llama.cpp cd llama.cpp # macOS make # Linux с CUDA make LLAMA_CUDA=1 # Windows (CMake) cmake -B build cmake --build build --config Release

#Python bindings

pip install llama-cpp-python
import llama_cpp_python as llama # Загрузка модели llm = llama.Llama( model_path="./models/llama-3.1-8b-Q4_K_M.gguf", n_ctx=4096, # размер контекста n_threads=8, # CPU threads n_gpu_layers=0, # 0 = CPU, >0 = GPU offload verbose=False ) # Генерация output = llm( "Расскажи о Python", max_tokens=256, temperature=0.7, top_p=0.9, stop=["\n\n"] ) print(output["choices"][0]["text"]) # Streaming for chunk in llm( "Напиши функцию", max_tokens=512, stream=True ): print(chunk["choices"][0]["text"], end='')

#Chat формат

from llama_cpp import Llama llm = Llama( model_path="./models/llama-3.1-8b-Q4_K_M.gguf", n_ctx=4096 ) # Создание chat completion output = llm.create_chat_completion( messages=[ {"role": "system", "content": "Ты — Python разработчик"}, {"role": "user", "content": "Напиши decorator для кэширования"} ], max_tokens=512, temperature=0.2 ) print(output["choices"][0]["message"]["content"])

#GPU Offload

# Частичный offload на GPU llm = llama.Llama( model_path="./models/llama-3.1-8b-Q4_K_M.gguf", n_gpu_layers=35, # количество слоёв на GPU n_ctx=4096 ) # Полный offload (если помещается) llm = llama.Llama( model_path="./models/llama-3.1-8b-Q4_K_M.gguf", n_gpu_layers=-1, # все слои на GPU main_gpu=0 # индекс GPU )

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

# Базовая генерация ./main -m models/llama-3.1-8b-Q4_K_M.gguf \ -p "Расскажи о Python" \ -n 256 \ --temp 0.7 # Chat режим ./main -m models/llama-3.1-8b-Q4_K_M.gguf \ -i \ --color # С системным промптом ./main -m models/llama-3.1-8b-Q4_K_M.gguf \ --system-prompt "Ты — Python разработчик" \ -p "Напиши функцию" \ -n 512 # Batch processing ./main -m models/llama-3.1-8b-Q4_K_M.gguf \ -f prompts.txt \ -n 256 \ -o output.txt

#4. vLLM

vLLM — оптимизированный serving engine для production. В 2-4x быстрее HuggingFace Transformers.

#Установка

pip install vllm

#API сервер

# Запуск сервера python -m vllm.entrypoints.api_server \ --model meta-llama/Llama-2-7b-chat-hf \ --port 8000 \ --host 0.0.0.0 # С квантованием python -m vllm.entrypoints.api_server \ --model mistralai/Mistral-7B-Instruct-v0.2 \ --quantization awq \ --port 8000 # С несколькими GPU python -m vllm.entrypoints.api_server \ --model meta-llama/Llama-2-70b-chat-hf \ --tensor-parallel-size 4 \ --port 8000

#Python клиент

from vllm import LLM, SamplingParams # Инициализация llm = LLM( model="meta-llama/Llama-2-7b-chat-hf", gpu_memory_utilization=0.9, tensor_parallel_size=1 ) # Параметры генерации sampling_params = SamplingParams( temperature=0.7, top_p=0.9, max_tokens=256, stop=["\n\n"] ) # Генерация prompts = [ "Напиши функцию на Python", "Объясни что такое OOP", "Как работать с asyncio?" ] outputs = llm.generate(prompts, sampling_params) for output in outputs: print(f"Prompt: {output.prompt}") print(f"Generated: {output.outputs[0].text}\n")

#OpenAI-compatible API

from openai import OpenAI # vLLM предоставляет совместимый API client = OpenAI( base_url="http://localhost:8000/v1", api_key="not-needed" ) response = client.chat.completions.create( model="meta-llama/Llama-2-7b-chat-hf", messages=[ {"role": "user", "content": "Привет!"} ] ) print(response.choices[0].message.content) # Streaming stream = client.chat.completions.create( model="meta-llama/Llama-2-7b-chat-hf", messages=[{"role": "user", "content": "Расскажи о Python"}], stream=True ) for chunk in stream: if chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end='')

#Continuous Batching

vLLM использует PagedAttention и continuous batching:

Traditional batching:
Request A: [████████████████]
Request B: [                ] ← ждёт завершения A
Request C: [                ] ← ждёт завершения A

vLLM continuous batching:
Request A: [██][██][██][██]
Request B:    [██][██][██][██] ← добавляется dynamically
Request C:       [██][██][██][██] ← добавляется dynamically

#5. Требования к железу

#Минимальные требования

МодельFP16GGUF Q4_K_MGPU (GPTQ 4-bit)
7B14GB4.2GB6GB
13B26GB8GB10GB
34B68GB20GB24GB
70B140GB40GB48GB

#Рекомендации

Для разработки (7-13B модели):

  • Mac M1/M2: 16GB+ RAM
  • NVIDIA GPU: RTX 3060 12GB или лучше
  • CPU: 16GB+ RAM, 8+ cores

Для production (13-34B модели):

  • NVIDIA GPU: RTX 4090 24GB или A100 40GB
  • RAM: 32GB+
  • Storage: NVMe SSD для быстрой загрузки моделей

Для больших моделей (70B+):

  • Multi-GPU: 2-4x A100 80GB
  • Или использовать quantization (Q4_K_M)

#Проверка совместимости

import torch def check_gpu_compatibility(): if not torch.cuda.is_available(): print("CUDA не доступен — только CPU inference") return gpu_name = torch.cuda.get_device_name(0) gpu_memory = torch.cuda.get_device_properties(0).total_memory / 1024**3 print(f"GPU: {gpu_name}") print(f"VRAM: {gpu_memory:.1f}GB") # Рекомендуемые модели if gpu_memory >= 40: print("Можно запускать: 7B, 13B, 34B (Q4), 70B (Q2)") elif gpu_memory >= 24: print("Можно запускать: 7B, 13B (Q4), 34B (Q2)") elif gpu_memory >= 12: print("Можно запускать: 7B, 13B (Q3)") elif gpu_memory >= 8: print("Можно запускать: 7B (Q4)") else: print("Мало VRAM — используйте CPU с GGUF или облачные API") check_gpu_compatibility()

#6. Интеграция с FastAPI

#Ollama + FastAPI

from fastapi import FastAPI, HTTPException from pydantic import BaseModel import ollama from typing import List, Optional app = FastAPI() class ChatRequest(BaseModel): message: str model: str = "llama3.1" temperature: float = 0.7 max_tokens: int = 512 conversation_history: List[dict] = [] class ChatResponse(BaseModel): response: str model: str tokens_per_second: Optional[float] = None @app.post("/chat", response_model=ChatResponse) async def chat(request: ChatRequest): import time start = time.time() messages = request.conversation_history + [ {"role": "user", "content": request.message} ] try: response = ollama.chat( model=request.model, messages=messages, options={ "temperature": request.temperature, "num_predict": request.max_tokens } ) elapsed = time.time() - start tokens = len(response["message"]["content"].split()) return ChatResponse( response=response["message"]["content"], model=request.model, tokens_per_second=tokens / elapsed if elapsed > 0 else None ) except Exception as e: raise HTTPException(status_code=500, detail=str(e))

#llama.cpp + FastAPI

from fastapi import FastAPI from pydantic import BaseModel import llama_cpp_python as llama from typing import Optional app = FastAPI() # Глобальная модель (lazy loading) _llm: Optional[llama.Llama] = None def get_llm() -> llama.Llama: global _llm if _llm is None: _llm = llama.Llama( model_path="./models/llama-3.1-8b-Q4_K_M.gguf", n_ctx=4096, n_threads=8 ) return _llm class GenerationRequest(BaseModel): prompt: str max_tokens: int = 256 temperature: float = 0.7 top_p: float = 0.9 class GenerationResponse(BaseModel): text: str tokens_per_second: float @app.post("/generate", response_model=GenerationResponse) async def generate(request: GenerationRequest): import time start = time.time() llm = get_llm() output = llm( request.prompt, max_tokens=request.max_tokens, temperature=request.temperature, top_p=request.top_p ) elapsed = time.time() - start text = output["choices"][0]["text"] tokens = len(text.split()) return GenerationResponse( text=text, tokens_per_second=tokens / elapsed if elapsed > 0 else 0 ) @app.on_event("startup") async def startup_event(): # Preload модель при старте get_llm()

#Streaming endpoint

from fastapi import FastAPI from fastapi.responses import StreamingResponse import ollama import json app = FastAPI() class StreamRequest(BaseModel): message: str model: str = "llama3.1" @app.post("/chat/stream") async def chat_stream(request: StreamRequest): async def generate(): stream = ollama.chat( model=request.model, messages=[{"role": "user", "content": request.message}], stream=True ) for chunk in stream: content = chunk["message"]["content"] yield f"data: {json.dumps({'content': content})}\n\n" yield "data: [DONE]\n\n" return StreamingResponse( generate(), media_type="text/event-stream" )

#7. Выбор инструмента

#Decision tree

Нужен ли production serving с высокой throughput?
├─ Да → vLLM
│
└─ Нет → Для чего?
    ├─ Быстрый старт / разработка → Ollama
    ├─ GUI для тестирования → LM Studio
    ├─ CPU inference / embeddings → llama.cpp
    └─ Custom integration → llama.cpp Python

#Сравнение

ИнструментCPUGPUStreamingAPIСложность
Ollama✅✅✅✅Низкая
LM Studio✅✅✅✅Низкая
llama.cpp✅✅✅❌Средняя
vLLM❌✅✅✅Высокая

Далее: Оценка LLM