Локальный AI-ассистент для заметок: Транскрипция и суммаризация без облаков 2026 | AiManual
AiManual Logo Ai / Manual.
16 Мар 2026 Гайд

Собираем локальный ассистент для заметок с транскрипцией и суммаризацией на базе open-source LLM

Полный гайд по сборке приватного ассистента для заметок на базе Whisper 3.1 и Llama 4. Установка, код, оптимизация. Работает оффлайн.

Почему все платят за Bluedot, когда можно собрать свое и не посылать записи встреч в облако?

Представьте: у вас закончилась важная встреча. Вы хотите быстро получить структурированные заметки, выводы и список действий. Bluedot, Otter.ai и другие сервисы делают это хорошо. За одну небольшую проблему: все ваши разговоры (включая обсуждение коммерческой тайны, личных дел или медицинских диагнозов) летят на чужие серверы. Где-то в Калифорнии или Сингапуре.

В 2026 году приватность - не паранойя, а базовое требование. Особенно если вы работаете в юриспруденции, медицине или в стартапе на стадии идеи. Хорошая новость: сегодня можно собрать систему, которая работает не хуже коммерческих аналогов, но все данные остаются на вашем ноутбуке или сервере. Без ежемесячных подписок, без лимитов на длительность аудио, без слежки.

Главный миф: «Локальные модели работают хуже облачных». Это было правдой в 2023 году. Сегодня (март 2026) open-source модели вроде Llama 4 7B по качеству суммаризации догоняют GPT-4, а Whisper 3.1 транскрибирует с точностью 98% даже с акцентами. Разрыв закрылся.

1 Выбираем стек: что взять в 2026 году?

Пайплайн прост: аудиофайл → транскрипция → текст → суммаризация/структурирование. Но выбор конкретных инструментов определяет, будет ли система летать или еле ползти.

Задача Инструмент (версия на март 2026) Почему именно он Требования RAM/VRAM
Транскрипция аудио в текст OpenAI Whisper 3.1 (large-v3-turbo) Новая версия с ускоренной инференцией на CPU. Поддерживает 100+ языков. Качество близкое к human-level. Работает без GPU. ~2-3 GB RAM (CPU)
Суммаризация и структурирование Meta Llama 4 7B (через Ollama 0.6.4) Баланс скорости и качества. 7B параметров достаточно для отличной суммаризации, но модель помещается в 8GB VRAM (или работает на CPU с квантованием). Llama 4 - самая новая архитектура на момент написания. 8GB VRAM (полная версия) или 6GB RAM (квантованная на CPU)
Оркестрация Python 3.11+ с FastAPI Простой скрипт или веб-интерфейс. FastAPI дает асинхронность для обработки длинных аудио. Минимальные

Альтернативы? Конечно. Для транскрипции есть Faster-Whisper (еще быстрее) или Paraformer (специально для русского). Но Whisper 3.1 - золотой стандарт. Для LLM можно взять Qwen2.5 7B или Gemma 2 7B. Они тоже отлично справляются. Но экосистема Ollama + Llama сейчас самая отполированная для локального запуска.

💡
Хотите более продвинутую систему с GUI и дизаризацией? У нас есть подробный гайд по TranscriptionSuite - полному решению для локальной транскрипции.

2 Устанавливаем и настраиваем: 20 минут вместо вечера

Раньше настроить локальную LLM было как собрать двигатель в темноте. Сегодня - три команды в терминале.

Сначала ставим Ollama (утилита для запуска LLM):

# На Linux/macOS
curl -fsSL https://ollama.ai/install.sh | sh

# Загружаем Llama 4 7B (квантованную версию, если мало памяти)
ollama pull llama4:7b  # или llama4:7b-q4_K_M для 4-битного квантования

Проверяем, что модель загрузилась:

ollama run llama4:7b "Привет! Напиши коротко о себе."

Теперь Whisper. Если у вас есть GPU с 8GB+ памяти, лучше использовать GPU-версию. Но CPU работает вполне сносно для записей до часа.

pip install openai-whisper==2026.1.0  # или pip install faster-whisper для ускоренной версии
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu124  # для GPU (CUDA 12.4)

Внимание: Whisper large-v3-turbo весит около 3GB. При первом запуске он скачает модель - убедитесь, что есть интернет и место на диске. Потом работает полностью оффлайн.

3 Пишем ядро: Python-скрипт, который все делает сам

Вот полный скрипт, который берет аудиофайл и возвращает структурированные заметки. Сохраните его как note_assistant.py.

import whisper
import json
import subprocess
import tempfile
from pathlib import Path
import requests  # для запросов к Ollama API

class LocalNoteAssistant:
    def __init__(self, whisper_model="large-v3-turbo", llm_model="llama4:7b"):
        """Инициализация моделей"""
        print(f"Загружаем Whisper {whisper_model}...")
        self.transcriber = whisper.load_model(whisper_model)
        self.llm_model = llm_model
        self.ollama_url = "http://localhost:11434/api/generate"
        
    def transcribe_audio(self, audio_path):
        """Транскрибируем аудио в текст"""
        print(f"Транскрибируем {audio_path}...")
        
        # Если файл не WAV, конвертируем (Whisper любит WAV)
        audio_ext = Path(audio_path).suffix.lower()
        if audio_ext not in ['.wav', '.flac']:
            with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as tmp:
                # Конвертируем через ffmpeg (должен быть установлен)
                subprocess.run([
                    'ffmpeg', '-i', audio_path, 
                    '-acodec', 'pcm_s16le', '-ar', '16000', '-ac', '1',
                    tmp.name, '-y'
                ], capture_output=True)
                audio_path = tmp.name
        
        result = self.transcriber.transcribe(
            audio_path,
            language='ru',  # явно указываем язык, если знаем
            fp16=False  # на CPU лучше выключить
        )
        return result['text']
    
    def summarize_with_llm(self, text, prompt_template=None):
        """Суммаризируем и структурируем текст через LLM"""
        if prompt_template is None:
            prompt_template = """Текст встречи:
{text}

Создай структурированные заметки в формате JSON:
1. Краткое резюме (3-4 предложения)
2. Ключевые темы (массив строк)
3. Действия (массив объектов с полями "кто", "что", "срок")
4. Решения (массив строк)
5. Открытые вопросы (массив строк)

Только JSON, без дополнительного текста:"""
        
        prompt = prompt_template.format(text=text[:12000])  # ограничиваем длину
        
        payload = {
            "model": self.llm_model,
            "prompt": prompt,
            "stream": False,
            "options": {
                "temperature": 0.1,  # низкая температура для более предсказуемого JSON
                "num_predict": 2000
            }
        }
        
        try:
            response = requests.post(self.ollama_url, json=payload, timeout=300)
            response.raise_for_status()
            result = response.json()
            
            # Пытаемся вытащить JSON из ответа LLM
            response_text = result['response']
            
            # Ищем JSON между  и  или просто парсим весь текст
            import re
            json_match = re.search(r'\n(.*?)\n', response_text, re.DOTALL)
            if json_match:
                json_str = json_match.group(1)
            else:
                # Пытаемся найти JSON с начала
                json_match = re.search(r'\{[\s\S]*\}', response_text)
                json_str = json_match.group(0) if json_match else response_text
            
            return json.loads(json_str)
            
        except Exception as e:
            print(f"Ошибка при работе с LLM: {e}")
            return {"error": str(e), "raw_response": result.get('response', '')}
    
    def process_meeting(self, audio_path):
        """Полный пайплайн: аудио → текст → структурированные заметки"""
        print("Начинаем обработку...")
        
        # Шаг 1: Транскрипция
        transcript = self.transcribe_audio(audio_path)
        print(f"Транскрипция готова. Длина: {len(transcript)} символов")
        
        # Сохраняем сырую транскрипцию
        with open("transcript.txt", "w", encoding="utf-8") as f:
            f.write(transcript)
        
        # Шаг 2: Суммаризация
        print("Суммаризируем через LLM...")
        structured_notes = self.summarize_with_llm(transcript)
        
        # Сохраняем результат
        output_file = "meeting_notes.json"
        with open(output_file, "w", encoding="utf-8") as f:
            json.dump({
                "transcript": transcript,
                "structured_notes": structured_notes
            }, f, ensure_ascii=False, indent=2)
        
        print(f"Готово! Результат в {output_file}")
        return structured_notes

# Использование
if __name__ == "__main__":
    assistant = LocalNoteAssistant()
    
    # Обрабатываем аудиофайл
    result = assistant.process_meeting("meeting_record.mp3")
    print(json.dumps(result, ensure_ascii=False, indent=2))

Это базовая версия. В реальности добавьте обработку ошибок, прогресс-бар для транскрипции, кэширование. Но для старта хватит.

💡
Для более сложных сценариев (например, анализ нескольких встреч вместе) посмотрите наш гайд по Meeting-LLM с RAG-архитектурой.

Подводные камни, которые вы не найдете в туториалах

Теперь о том, о чем молчат блогеры. Тот опыт, который получаешь только набив шишки.

1. Память - ваше главное ограничение

Whisper large-v3-turbo на CPU съедает 2-3GB оперативки. Llama 4 7B в полной версии требует 8GB VRAM. Если у вас ноутбук с 16GB RAM и без дискретной видеокарты, будет тяжело.

Решение:

  • Используйте квантованные версии Llama: llama4:7b-q4_K_M (4 бита) работает на CPU с 6GB RAM.
  • Для Whisper возьмите среднюю модель: medium вместо large. Качество проседает на 2-3%, но память экономит в 2 раза.
  • Или используйте аренду GPU в облаке (ирония, но иногда нужно). За $0.5/час получаете A100.

2. Whisper ненавидит фоновый шум

Запись с конференц-связи, где кто-то стучит по клавиатуре? Whisper может вставить в транскрипцию случайные слова. Особенно если есть эхо.

Решение: Предварительная обработка аудио. Простой фильтр шума через librosa или noisereduce:

import noisereduce as nr
import librosa

def denoise_audio(input_path, output_path):
    y, sr = librosa.load(input_path, sr=16000)
    # Выбираем кусок с шумом (первые 0.5 секунды)
    noise_sample = y[:int(0.5 * sr)]
    y_denoised = nr.reduce_noise(y=y, sr=sr, y_noise=noise_sample)
    librosa.output.write_wav(output_path, y_denoised, sr)

3. LLM галлюцинирует с JSON

Вы просите JSON, а модель возвращает «Конечно, вот JSON:» и потом текст. Или забывает закрыть скобку. Особенно при высокой температуре.

Решение:

  • Ставьте temperature=0.1 или даже 0 для структурированных ответов.
  • Используйте guided generation (Ollama поддерживает через grammars).
  • Или парсите ответ regex, как в коде выше.
💡
Если нужно работать с очень длинными документами (100k+ токенов), изучите наш опыт в статье про Pathway + Ollama + Llama 2.5.

Частые вопросы (которые вы зададите через час после запуска)

«У меня MacBook M3, будет ли работать?»

Будет, и еще как. Apple Silicon (M1/M2/M3) отлично оптимизирован под ML. Установите arm64 версию PyTorch и используйте mps бэкенд. Скорость будет сравнима с GPU среднего класса.

# Для Mac с Apple Silicon
import torch
self.transcriber = whisper.load_model("large-v3-turbo").to("mps")

«Как обрабатывать записи длиннее часа?»

Whisper сам разбивает длинные аудио на чанки. Но если подать 3-часовую запись, может кончиться память. Разбивайте вручную:

# Разбить на части по 30 минут через ffmpeg
ffmpeg -i long_meeting.mp3 -f segment -segment_time 1800 -c copy part_%03d.mp3

Обработайте каждый файл отдельно, затем объедините транскрипции перед отправкой в LLM.

«Можно ли заставить это работать в реальном времени?»

Можно, но сложно. Whisper есть streaming-версия (whisper.cpp), но качество ниже. Для реального времени лучше взять специализированные модели вроде Silero V3. Но для заметок после встреч это избыточно.

«Как добавить поддержку нескольких языков?»

Whisper определяет язык автоматически. Но если в одной встрече говорят на русском и английском, будут ошибки. Решение: указать language='ru' или language='en' явно, если знаете основной язык. Для смешанной речи лучше использовать модель, обученную на code-switching данных (пока таких open-source мало).

Совет по масштабированию: Если нужно обрабатывать десятки встреч в день, выносите систему на отдельный сервер. Возьмите VPS с GPU (например, этот вариант дает хорошее соотношение цены и мощности). Поднимите FastAPI, добавьте очередь задач (Celery + Redis), и у вас будет свой приватный Bluedot для всей команды.

Что дальше? Куда развивать систему

Базовая версия работает. Но настоящая магия начинается с доработками:

  • RAG поверх прошлых встреч: Чтобы LLM могла сказать «Месяц назад мы уже обсуждали этот контракт». Смотрите наш гид по RAG.
  • Диаризация: Кто что сказал? Добавьте AnythingLLM Meeting Assistant с pyannote.audio для разделения голосов.
  • Интеграция с календарем: Автоматически обрабатывать записи из Zoom/Teams, вытаскивая их из календаря.
  • Анализ тональности: Была ли встреча напряженной? Llama может анализировать эмоциональную окраску.

Самое главное - вы теперь контролируете свои данные. Ни один промпт не уйдет в OpenAI. Ни одна запись не попадет на серверы Microsoft. Вы платите только за железо (которое у вас уже есть).

Начинайте с простого скрипта. Первая успешная обработка встречи, которая сохранила вам час ручного конспектирования, окупит все время настройки. А дальше - апгрейд по мере необходимости. Система модульная, все можно заменить.

Потому что лучшая система - та, которую вы собрали сами под свои нужды. Даже если в ней есть костыли. Они ваши костыли.

Подписаться на канал