docs: 将仓库代码注释统一为中文
CI / docs-check (push) Canceled after 0s
CI / backend-test (push) Canceled after 0s
CI / service-test (push) Canceled after 0s
CI / frontend-test (push) Canceled after 0s
CI / rust-core (push) Canceled after 0s
CI / docs-check (pull_request) Canceled after 0s
CI / backend-test (pull_request) Canceled after 0s
CI / service-test (pull_request) Canceled after 0s
CI / frontend-test (pull_request) Canceled after 0s
CI / rust-core (pull_request) Canceled after 0s

This commit is contained in:
2026-09-10 00:40:56 +08:00
parent 51c592841d
commit d703ab64e3
249 changed files with 707 additions and 900 deletions
+1 -1
View File
@@ -1 +1 @@
"""Optional local inference; importing this package does not load model libraries."""
"""可选的本地推理;导入此包不会加载模型库。"""
+1 -1
View File
@@ -1,4 +1,4 @@
"""Reviewed model identities. Runtime never resolves a moving model revision."""
"""经过审核的模型标识;运行时绝不解析浮动的模型版本。"""
from dataclasses import asdict, dataclass
+1 -1
View File
@@ -1,4 +1,4 @@
"""User-triggered installation of the fixed optional CUDA runtime on Windows."""
"""用户触发在 Windows 上安装固定的可选 CUDA 运行时。"""
import asyncio
import json
import os
+1 -1
View File
@@ -1,4 +1,4 @@
"""Explicit resumable downloads; inference itself never fetches weights."""
"""由用户显式触发、支持断点续传的下载;推理过程本身绝不下载权重。"""
from __future__ import annotations
import asyncio
+4 -4
View File
@@ -1,4 +1,4 @@
"""Pipe adapter for event loops without asyncio subprocess support (Windows reload)."""
"""用于没有异步子进程支持的事件循环的管道适配器(Windows 重新加载)。"""
from __future__ import annotations
import asyncio
@@ -33,14 +33,14 @@ class _Output:
self.limit = limit
async def readline(self):
# Bound allocations even when the worker produces a malformed line.
# 即使工作线程生成格式错误的行,分配也会受到限制。
return await asyncio.to_thread(self.pipe.readline, self.limit + 1)
class ThreadedProcess:
def __init__(self, args, *, env, limit, creationflags=0):
# Spawn synchronously so cancellation cannot leave an unowned process.
# Blocking pipe I/O and reaping run in threads, never on the server loop.
# 同步创建进程,避免取消操作留下无人管理的子进程。阻塞式管道 I/O 与进程回收在线程中执行,
# 不占用服务器事件循环。
self.process = subprocess.Popen(
args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL, env=env, creationflags=creationflags,
+1 -1
View File
@@ -1,4 +1,4 @@
"""Bound embedding result frames so large notes do not exceed pipe line limits."""
"""绑定嵌入结果帧,因此大笔记不会超出管道限制。"""
import json
+2 -2
View File
@@ -1,4 +1,4 @@
"""Bounded, cancellable model subprocesses with CPU as the default device."""
"""有界、可取消的模型子流程,以 CPU 作为默认设备。"""
from __future__ import annotations
import asyncio
@@ -114,7 +114,7 @@ class Runtime:
self.active[ticket] = key
self.active_files[ticket] = {str(Path(payload[name]).resolve()) for name in ("source", "reference") if payload.get(name)}
queue_seconds = time.monotonic() - queued_at
# Keep the reservation while replacing a failed CUDA process with CPU.
# 用 CPU 进程替换失败的 CUDA 进程时,继续占用原有资源配额。
for device in (["cuda", "cpu"] if config.device == "cuda" else ["cpu"]):
started = time.monotonic()
diagnostics = dict(model=CATALOG[key].repository, revision=CATALOG[key].revision,
+7 -7
View File
@@ -1,4 +1,4 @@
"""One offline inference process. Heavy libraries stay out of the API process."""
"""单个离线推理进程;重量级依赖不会加载到 API 进程中。"""
from __future__ import annotations
import contextlib
@@ -26,7 +26,7 @@ def decode(path, *, limit_seconds=3600, warnings=None):
corrupt += 1
if corrupt > 100:
raise ValueError("Too many damaged audio packets")
# Retain the missing packet's duration as silence so later timestamps do not shift.
# 将丢失数据包的持续时间保留为静音,以便后面的时间戳不会发生变化。
missing = max(0, round(float((packet.duration or 0) * (packet.time_base or 0)) * 16000))
samples += missing
if samples > limit_seconds * 16000:
@@ -58,7 +58,7 @@ def decode(path, *, limit_seconds=3600, warnings=None):
def speech_regions(audio):
"""Energy-based segmentation, not word alignment; retain original sample offsets."""
"""基于能量的切分,而不是词对齐;保留原始样本偏移量。"""
import numpy as np
window = 480
energies = [float(np.sqrt(np.mean(audio[i:i + window] ** 2))) for i in range(0, len(audio), window)]
@@ -140,7 +140,7 @@ def run(request):
model_kwargs={"attn_implementation": "sdpa"})
loaded = time.monotonic()
result = model.encode(payload["texts"], batch_size=4, normalize_embeddings=True, show_progress_bar=False).tolist()
# Count the tokenizer's actual encoded input, not characters or words.
# 计算分词器的实际编码输入,而不是字符或单词。
usage = {"input_tokens": int(model.tokenize(payload["texts"])["attention_mask"].sum())}
elif operation == "transcription":
from qwen_asr import Qwen3ASRModel
@@ -166,7 +166,7 @@ def run(request):
loaded = time.monotonic()
first = voice_embedding(model, decode(payload["source"]), device)
second = voice_embedding(model, decode(payload["reference"]), device)
# Similarity, not a calibrated identity probability.
# 相似性,不是校准的身份概率。
result = {"score": max(0.0, min(1.0, float(torch.dot(first, second))))}
elif operation == "diarization":
model = speaker_model(path, device)
@@ -198,14 +198,14 @@ def run(request):
if __name__ == "__main__":
request = json.loads(sys.stdin.buffer.read())
# Third-party progress/logging must never corrupt the protocol or leak into API errors.
# 第三方进度/日志记录绝不能破坏协议或泄漏到 API 错误。
with contextlib.redirect_stdout(sys.stderr):
try:
response = run(request)
except (ImportError, ModuleNotFoundError):
response = {"error_code": "LOCAL_RUNTIME_DEPENDENCY_MISSING", "message": "本地模型运行依赖不完整,请重新运行安装脚本。"}
except Exception as exc:
# Only device failures allow the host to retry once in a fresh CPU process.
# 只有设备故障才允许主机在新的 CPU 进程中重试一次。
import torch
cuda_failure = isinstance(exc, CudaInitializationError)
cuda_oom = request.get("_actual_device") == "cuda:0" and isinstance(exc, torch.cuda.OutOfMemoryError)