541df29722
Use the same manual_seed for every chunk and normalize per-segment peaks before concat so long voiceovers no longer sound like different speakers between segments. Co-authored-by: Cursor <cursoragent@cursor.com>
172 lines
6.6 KiB
Python
172 lines
6.6 KiB
Python
"""
|
||
Trading Studio 全局配置模块
|
||
统一存放局域网节点、模型名称、固定 Prompt 及本地路径。
|
||
|
||
服务器本地覆盖:复制 .env.example 为 .env 并修改(不入 Git),无需改 config.py。
|
||
"""
|
||
|
||
import os
|
||
from pathlib import Path
|
||
|
||
|
||
def _load_dotenv() -> None:
|
||
"""加载项目根目录 .env(简单 KEY=VALUE 格式,无第三方依赖)。"""
|
||
env_path = Path(__file__).resolve().parent / ".env"
|
||
if not env_path.is_file():
|
||
return
|
||
for raw in env_path.read_text(encoding="utf-8").splitlines():
|
||
line = raw.strip()
|
||
if not line or line.startswith("#") or "=" not in line:
|
||
continue
|
||
key, val = line.split("=", 1)
|
||
key = key.strip()
|
||
val = val.strip().strip('"').strip("'")
|
||
if key and key not in os.environ:
|
||
os.environ[key] = val
|
||
|
||
|
||
_load_dotenv()
|
||
|
||
|
||
def _env_str(key: str, default: str) -> str:
|
||
return os.environ.get(key, default).strip()
|
||
|
||
|
||
def _env_int(key: str, default: int) -> int:
|
||
try:
|
||
return int(os.environ.get(key, str(default)).strip())
|
||
except ValueError:
|
||
return default
|
||
|
||
|
||
def _env_bool(key: str, default: bool) -> bool:
|
||
raw = os.environ.get(key)
|
||
if raw is None:
|
||
return default
|
||
return raw.strip().lower() in ("1", "true", "yes", "on")
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 网络与服务
|
||
# ---------------------------------------------------------------------------
|
||
# 远程 Ollama 节点(局域网大模型审查润色)
|
||
# 生产环境请在 .env 中设置 OLLAMA_HOST,避免 git pull 冲突
|
||
OLLAMA_HOST = _env_str("OLLAMA_HOST", "192.168.8.64")
|
||
OLLAMA_PORT = _env_int("OLLAMA_PORT", 11434)
|
||
OLLAMA_URL = f"http://{OLLAMA_HOST}:{OLLAMA_PORT}/api/chat"
|
||
|
||
# 指定无限制版 Gemma4 模型
|
||
MODEL_NAME = _env_str("MODEL_NAME", "huihui_ai/gemma-4-abliterated:e4b")
|
||
|
||
# Gradio 中控固定端口(硬性死规则)
|
||
HOST = "0.0.0.0"
|
||
PORT = 5683
|
||
|
||
# HTTP 请求超时(秒)
|
||
OLLAMA_TIMEOUT = 60
|
||
|
||
# 健康检查快速超时(秒)— 避免平板首屏被长时间阻塞
|
||
HEALTH_CHECK_CONNECT_TIMEOUT = 2
|
||
HEALTH_CHECK_READ_TIMEOUT = 3
|
||
HEALTH_CHECK_CACHE_SECONDS = 30
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# LLM 系统 Prompt
|
||
# ---------------------------------------------------------------------------
|
||
SYSTEM_PROMPT = (
|
||
"你是一个冷静、极其严格的数字资产量化交易员。"
|
||
"请把下面这段口语化、包含结巴和逻辑混乱的交易复盘录音转写,"
|
||
"润色成一段逻辑清晰、行文通顺的 B 站长视频反思配音稿。"
|
||
"语气要内向、克制、严谨。"
|
||
"如果原视频中有由于心态不好、违背交易纪律(如手贱乱开仓、提前平仓)"
|
||
"导致少赚或亏损的部分,请用冷酷、严厉的语气狠狠地自我吐槽、反思该点。"
|
||
"去掉所有无意义的口头禅,字数不做删减。"
|
||
"【输出格式硬性要求】"
|
||
"只输出可直接朗读的纯文本正文,不要 Markdown(禁止 #、**、---、列表符号、emoji)。"
|
||
"不要写舞台提示(如前奏、转场、BGM、语气说明等括号备注)。"
|
||
"不要写「以下是润色后的文案」等前言,也不要写修改笔记或点评。"
|
||
"可用《》作为标题,正文按自然段换行即可。"
|
||
)
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 路径
|
||
# ---------------------------------------------------------------------------
|
||
BASE_DIR = Path(__file__).resolve().parent
|
||
INSTALL_DIR = Path("/opt/Trading_Studio")
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Faster-Whisper 配置
|
||
# ---------------------------------------------------------------------------
|
||
WHISPER_MODEL_SIZE = _env_str("WHISPER_MODEL_SIZE", "small")
|
||
WHISPER_DEVICE = "cuda"
|
||
WHISPER_COMPUTE_TYPE = "float16"
|
||
WHISPER_LANGUAGE = "zh"
|
||
WHISPER_MODEL_DIR = Path(_env_str("WHISPER_MODEL_DIR", str(BASE_DIR / "models" / "whisper")))
|
||
|
||
WHISPER_HF_REPO = {
|
||
"tiny": "Systran/faster-whisper-tiny",
|
||
"base": "Systran/faster-whisper-base",
|
||
"small": "Systran/faster-whisper-small",
|
||
"medium": "Systran/faster-whisper-medium",
|
||
"large-v2": "Systran/faster-whisper-large-v2",
|
||
"large-v3": "Systran/faster-whisper-large-v3",
|
||
}
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# ChatTTS 配置
|
||
# ---------------------------------------------------------------------------
|
||
# 固定音色 Embedding 存储路径
|
||
SPEAKER_EMB_PATH = BASE_DIR / "speaker_emb.pt"
|
||
|
||
# 合成音频输出目录
|
||
OUTPUT_DIR = BASE_DIR / "outputs"
|
||
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
||
|
||
# ChatTTS 采样率(Hz)
|
||
TTS_SAMPLE_RATE = 24000
|
||
|
||
# ChatTTS 模型本地目录(预下载后离线加载,避免访问 GitHub 超时)
|
||
CHATTTS_MODEL_DIR = Path(_env_str("CHATTTS_MODEL_DIR", str(BASE_DIR / "models" / "ChatTTS")))
|
||
|
||
# HuggingFace 镜像(国内服务器推荐)
|
||
HF_ENDPOINT = _env_str("HF_ENDPOINT", "https://hf-mirror.com")
|
||
HF_HUB_DOWNLOAD_TIMEOUT = _env_int("HF_HUB_DOWNLOAD_TIMEOUT", 600)
|
||
HF_HOME = Path(_env_str("HF_HOME", str(BASE_DIR / "models" / "hf_cache")))
|
||
|
||
# 音色样本时长建议(秒)
|
||
SPEAKER_SAMPLE_MIN_SEC = 10
|
||
SPEAKER_SAMPLE_MAX_SEC = 30
|
||
|
||
# TTS 推理默认参数(低 temperature 有助于音色稳定)
|
||
TTS_TEMPERATURE = 0.3
|
||
TTS_TOP_P = 0.7
|
||
TTS_TOP_K = 20
|
||
TTS_SPEED_PROMPT = "[speed_5]"
|
||
# 多段拼接时各段必须使用同一随机种子,否则音色会像「换了个人」
|
||
TTS_MANUAL_SEED = _env_int("TTS_MANUAL_SEED", 42)
|
||
# 段间静音间隔(秒)
|
||
TTS_SEGMENT_PAUSE_SEC = 0.35
|
||
|
||
# 单段 TTS 最大字数(超长稿按句切分后逐段合成再拼接;8GB 显存建议 ≤200)
|
||
TTS_MAX_CHARS_PER_CHUNK = _env_int("TTS_MAX_CHARS_PER_CHUNK", 200)
|
||
|
||
# ChatTTS 单段最大生成 token(越小越省显存,长句会自动切多段)
|
||
TTS_MAX_NEW_TOKEN = _env_int("TTS_MAX_NEW_TOKEN", 1024)
|
||
|
||
# 至少生成多少 audio token 才允许结束(防止首 token EOS → 无限递归重试)
|
||
TTS_MIN_NEW_TOKEN = _env_int("TTS_MIN_NEW_TOKEN", 16)
|
||
|
||
# GPT KV cache(关闭可省显存,但部分 transformers 版本会触发 CUDA assert)
|
||
TTS_ENABLE_CACHE = _env_bool("TTS_ENABLE_CACHE", True)
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 上传临时文件目录
|
||
# ---------------------------------------------------------------------------
|
||
UPLOAD_DIR = BASE_DIR / "uploads"
|
||
UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Git 仓库(文档引用)
|
||
# ---------------------------------------------------------------------------
|
||
GIT_REPO_URL = "https://git.bz121.com/dekun/Trading_Studio.git"
|