fix(openvino): клампинг отрицательных таймкодов + результаты тестов Intel/AMD

- Зачем:
  - OpenVINO GenAI может вернуть отрицательный end_ts, ломая формат транскрипта.
  - зафиксировать бенчмарки на Intel и AMD CPU для документации.
- Что:
  - backends/openvino.py: start/end клампятся через max(0, ...).
  - docs/gpu.md: полная таблица скорости Intel i7 vs AMD Ryzen 7 8845H.
  - сравнение качества medium int8 vs large-v3 fp16 vs CPU float32 на одном файле.
  - вывод: large-v3 OpenVINO (416с) быстрее medium CPU (734с) при лучшем качестве.
- Проверка:
  - uv run pytest -q — 124 passed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-22 11:10:48 +03:00
co-authored by Claude Opus 4.6
parent 29da69c595
commit 61908604a0
2 changed files with 31 additions and 21 deletions
+27 -19
View File
@@ -16,7 +16,7 @@
| Любой CPU (fallback) | `cpu` | faster-whisper (CTranslate2) | ~1.5x реалтайм |
| Apple Silicon (macOS) | `cpu` | faster-whisper (CTranslate2) | ~2x реалтайм |
\* Ожидаемая оценка на основе бенчмарков OpenVINO. Реальная скорость зависит от CPU и модели.
\* По результатам тестирования на Intel и AMD CPU. Реальная скорость зависит от CPU и модели.
## OpenVINO
@@ -39,22 +39,30 @@ OpenVINO ускоряет inference на x86 процессорах (Intel и AM
### Результаты тестирования OpenVINO
Тесты на Intel CPU (WSL2), реальные записи рабочих созвонов (русский, техтермины).
Реальные записи рабочих созвонов (русский, техтермины: SQL, PostgreSQL, LDAP, DLP и др.).
**Скорость (medium int8):**
**Скорость:**
| Файл | OpenVINO | CPU (CTranslate2) | Ускорение |
|------|----------|-------------------|-----------|
| 16 мин | 205с (3.4 мин) | 658с (11 мин) | **3.2x** |
| 24 мин | 224с (3.7 мин) | — | **~6.5x реалтайм** |
| Конфигурация | Intel i7 (WSL2) | AMD Ryzen 7 8845H | CPU float32 |
|---|---|---|---|
| OpenVINO medium int8, 16 мин | 171-205с | **185с** | 658-734с |
| OpenVINO medium int8, 42 мин | 413с (6.9 мин) | — | — |
| OpenVINO large-v3 fp16, 16 мин | — | **416с** | — |
**Качество (medium int8):**
- Содержание и технические термины распознаются корректно
- Галлюцинаций и повторов не обнаружено (ни на 16, ни на 24 мин)
- Качество сопоставимо с CPU float32 и CUDA float16
- OpenVINO даёт более гранулярные сегменты (174 vs 97 на том же файле)
**Ускорение vs CPU:** **3-4x** на обоих процессорах (Intel и AMD).
> Тестирование на AMD CPU пока не проводилось.
**Качество (сравнение на одном файле, 16 мин, AMD Ryzen 7 8845H):**
| | OpenVINO medium int8 | OpenVINO large-v3 fp16 | CPU medium float32 |
|---|---|---|---|
| Время | 185с | 416с | 734с |
| Техтермины | корректно | корректно | корректно |
| Галлюцинации | нет | нет | нет |
| Характерные ошибки | "Атака новенького" (вместо "а так, новенького") | — | те же ошибки, что medium int8 |
| Пунктуация | базовая | заметно лучше | базовая |
`large-v3` на OpenVINO качественнее `medium`, но в 2.2 раза медленнее. При этом `large-v3` на OpenVINO (416с)
быстрее, чем `medium` на чистом CPU (734с) — можно получить и лучшее качество, и выше скорость.
## Настройка по платформам
@@ -87,13 +95,13 @@ winget install -e --id Nvidia.CUDA --version 12.9 # требует запус
Замеры на RTX 3060 Laptop (6 GB) и Intel CPU (WSL2):
| Конфигурация | 16 мин файл | 24 мин файл | Отн. скорость |
| Конфигурация | 16 мин файл | 42 мин файл | Отн. скорость |
|-------------|-------------|-------------|---------------|
| GPU + medium float16 | ~35с | | ~19x реалтайм |
| GPU + large-v3 float16 | ~90с | | ~7x реалтайм |
| **OpenVINO + medium int8** | **205с (3.4 мин)** | **224с (3.7 мин)** | **~4.7-6.5x реалтайм** |
| CPU + medium float32 | 658с (11 мин) | | ~1.5x реалтайм |
| CPU + large-v3 int8 | 839с (14 мин) | | ~1:1 реалтайм |
| GPU + medium float16 | ~35с | ~133с | ~19x реалтайм |
| GPU + large-v3 float16 | ~90с | ~350с | ~7x реалтайм |
| **OpenVINO + medium int8** | **171-205с** | **413с (6.9 мин)** | **~4-6x реалтайм** |
| CPU + medium float32 | 658с (11 мин) | ~26 мин | ~1.5x реалтайм |
| CPU + large-v3 int8 | 839с (14 мин) | ~37 мин | ~1:1 реалтайм |
## Результаты тестирования качества
+4 -2
View File
@@ -108,9 +108,11 @@ class OpenVINOBackend:
segments: list[Segment] = []
if hasattr(result, "chunks") and result.chunks:
for chunk in result.chunks:
start = max(0.0, chunk.start_ts)
end = max(start, chunk.end_ts)
seg = Segment(
start=chunk.start_ts,
end=chunk.end_ts,
start=start,
end=end,
text=chunk.text,
)
if on_segment is not None: