~/potatohd.ruEN
← Все статьи
10 августа 2026·7 мин

Наговори и Saylo: как устроен сервис расшифровки на своих GPU

GoTemporalGPUбиллинг

Пользователь загружает запись созвона — через несколько минут получает текст и протокол встречи. Всё остальное в этом посте — про то, что стоит за этими двумя предложениями.

Главная страница Наговори: заголовок «Час записи — в готовый документ за пять минут» и превью протокола встречи с решениями, задачами и цитатами
Наговори — российский контур

#Файл не проходит через бэкенд

Первое решение — самое дешёвое и самое полезное. Аудио бывает на несколько часов и гигабайты; гнать его через приложение означает держать соединение открытым всё время загрузки, есть память на буферах и упираться в лимиты прокси.

Браузер получает presigned-ссылку от Go API, грузит файл напрямую в S3, затем создаёт задачу; API резервирует минуты и запускает воркфлоу Temporal
Бэкенд выдаёт пропуск и уходит с дороги

Бэкенд на Go выдаёт presigned-ссылку и на этом самоустраняется: файл едет из браузера прямо в бакет. Приложение узнаёт о записи, только когда фронт приходит создавать задачу. Побочный эффект — бэкенд можно перевыкатывать посреди чужой часовой загрузки, и ничего не сломается.

#Одна видеокарта, несколько воркеров

На GPU-хосте живёт не один процесс: ASR, TTS, что-нибудь ещё. Видеокарта одна. Если два воркера одновременно возьмут по задаче, обоим не хватит памяти, и упадут оба — причём не сразу, а на середине чужой часовой записи.

Очередь Temporal отдаёт активность воркеру на GPU-хосте; воркеры хоста сериализуются через лок в Redis, работающий воркер ходит в LiteLLM за ASR
Замок на слот хоста: в моменте на карте ровно одна задача

Поэтому перед тем как взять задачу, воркер берёт в Redis лок слота хоста и держит его до конца работы. Все воркеры одного хоста сериализуются через этот лок, сколько бы их ни было. Планировщик при этом ничего не знает про GPU: Temporal просто раздаёт активности, а физическое ограничение живёт там, где оно физически есть — на хосте.

Сама модель вызывается не напрямую, а через LiteLLM по OpenAI-совместимому API. Это выглядит как лишний слой, пока не понадобится сменить модель: id модели приходит в задаче, а какой именно чекпоинт за ним стоит — вопрос конфигурации шлюза, а не выкатки воркера.

#Биллинг: сначала резерв, потом факт

Поминутная оплата ставит неудобный вопрос: сколько списать, если длительность станет известна только в конце?

Жизненный цикл списания: резерв оценки при старте, подсчёт реальных минут, замена оценки фактом, возврат разницы
Резерв на старте, перерасчёт на финише — баланс не уходит в минус ни в какой момент

При старте задачи резервируется оценка, поэтому баланс не может уйти в минус, пока крутится воркфлоу. На финише оценка заменяется фактической длительностью, а разница возвращается. Если воркфлоу упал — возвращается всё: за сбой сервиса платит сервис.

Такой порядок — единственный, который переживает падение в середине. Списание по факту в конце даёт бесплатную работу тому, кто запустит десять задач разом на пустом балансе.

#Два бренда, один код

Главная страница Saylo: заголовок «Your searchable memory for every recording» и превью расшифровки с таймкодами и спикерами
Saylo — тот же бэкенд, другой рынок

Наговори и Saylo — буквально один и тот же код. Различия вынесены в конфигурацию, привязанную к организации пользователя: своя организация в провайдере идентичности, свой платёжный аккаунт, своя валюта, свой объём бесплатных минут, свой язык интерфейса. Запрос с домена saylo.pro попадает на свою биллинг-конфигурацию, и на этом всё отличие заканчивается.

Соблазн форкнуть код под второй рынок велик и обходится дорого через полгода: любая правка становится двумя правками, а расхождение обнаруживается на клиенте. Разделение по конфигу требует один раз аккуратно провести границу — и дальше оно бесплатно.

РешениеЧто оно покупает
Presigned-загрузка мимо бэкендадеплой не роняет чужие загрузки
Лок слота хоста в Redisодна задача на карту без знания планировщика о GPU
Модель за OpenAI-совместимым шлюзомсмена модели — конфигурация, а не выкатка
Резерв, потом перерасчётбаланс не уходит в минус даже при падении
Бренд как конфиг, а не форкодна правка вместо двух

#Где сейчас граница

Российский контур в проде целиком: оплата, поминутный учёт, счета для юрлиц. По международному контуру карточный приём платежей ещё доделывается — всё остальное, от входа до расшифровки, работает.

// свободен для заказов

Нужен сайт или сервис под ключ?