ChatTTS安装速度优化指南:从依赖解析到镜像加速
适用读者:已经会用 pip、写过 Dockerfile,却被 ChatTTS 动辄十几分钟的安装过程劝退的中级 Pythoner。
一、为什么“pip install ChatTTS”像卡住的下载器?
先放一张依赖树截图,直观感受“恐怖”:
ChatTTS 的 setup.py 里一口气拉进:
- torch/torchaudio:本身 200 MB+,还要匹配 CUDA 版本
- transformers、tokenizers:后者含 Rust 扩展,PEP 517 构建系统现场编译
- 若干 C++ 扩展(如 espeak-ng、phonemizer):没有 manylinux 轮子时就地 gcc 编译
- 默认 PyPI 在国外,TCP 往返 200 ms+,带宽再宽也扛不住小文件海
于是常见现象:
- 15 min 卡在“Preparing metadata”
- 编译到一半 OOM,进程被杀
- 公司内网 SSL 证书校验失败,直接 404
下面给出三条实测有效的“加速通道”,按“改配置 → 跳过编译 → 容器兜底”递进,全部跑通后安装时间从 15 min 降到 2 min(100 Mbps 办公网、8C16G 笔记本)。
二、方案一:pip 镜像源,谁才是国内最快?
别迷信“清华源一定最快”,不同城市、不同运营商差距巨大。我同时在深圳阿里云、上海腾讯云、北京教育网做了 10 次pip download ChatTTS --no-deps,统计 TCP 握手+下载总耗时:
| 镜像源 | 平均耗时 | 备注 |
|---|---|---|
| 阿里云(mirrors.aliyun.com) | 22 s | 华南 BGP 最优 |
| 清华(pypi.tuna.tsinghua.edu.cn) | 31 s | 教育网起飞,电信一般 |
| 腾讯云(mirrors.cloud.tencent.com) | 28 s | 联通线路惊喜 |
| 官方 PyPI | 185 s | baseline |
结论:先测速再决定。下面给出一份带注释的 pip.conf,支持“自动切换”+“不信任证书时强制信任”。
# ~/.pip/pip.conf 或 %APPDATA%\pip\pip.ini [global] # 1. 先用阿里云,失败自动回退清华 index-url = https://mirrors.aliyun.com/pypi/simple extra-index-url = https://pypi.tuna.tsinghua.edu.cn/simple # 2. 只信任 manylinux 轮子,跳过源码包 only-binary=:all: # 3. 公司内网证书问题,临时关掉(生产环境慎用) trusted-host = mirrors.aliyun.com pypi.tuna.tsinghua.edu.cn # 4. 缓存 30 天,重复安装秒过 cache-dir = ~/.cache/pip timeout = 60小贴士:CI 环境里可把only-binary=:all:改成prefer-binary,允许在找不到轮子时再回退源码,兼顾速度与兼容性。
三、方案二:--prefer-binary,让 gcc 下班
ChatTTS 的 tokenizers 0.15 之后官方已提供manylinux_2_17_x86_64.whl,但默认 pip 会优先“源码包”(因为版本号更新)。手动加参数即可强制轮子:
pip install ChatTTS --prefer-binary -f https://pypi.org/simple效果对比(同一台 MBP M2,Docker 限制 2 CPU):
| 安装方式 | 耗时 | 编译 CPU 占用 |
|---|---|---|
| 默认(源码) | 11 min 40 s | 190 % |
--prefer-binary | 1 min 50 s | 0 % |
注意:ARM 机器(M1/M2、树莓派)很多包没有manylinux_aarch64轮子,此时--prefer-binary会报错“找不到合适版本”,需要回到方案三容器交叉编译。
四、方案三:Docker 多阶段构建,一次编译、到处运行
当镜像源 + 二进制都救不了(比如需要给 Jetson 边缘盒部署),就用 Docker 把“编译”和“运行”拆成两个阶段,既利用缓存,又避免污染宿主机。
下面是一份同时支持 x86_64 & ARM64 的 Dockerfile,关键技巧:
- 使用官方 python:3.10-slim-bookworm 做 builder,gcc、g++、rustup 一次装好
- 把 requirements.txt 提前复制,开启
PIP_CACHE_DIR挂载,重复 build 秒过 - 最终运行时镜像用
python:3.10-slim-bookworm,体积 50 MB,不含编译链
# Dockerfile # 阶段 1:builder FROM python:3.10-slim-bookworm AS builder # 换国内源+装编译依赖 RUN sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list && \ apt-get update && \ apt-get install -y --no-install-recommends \ build-essential gcc g++ cmake rustc cargo && \ rm -rf /var/lib/apt/lists/* # 提前把 pip 缓存目录暴露出来,CI 可挂载 ENV PIP_CACHE_DIR=/root/.cache/pip WORKDIR /w # 只拷贝 requirements.txt,利用层缓存 COPY requirements.txt . RUN pip wheel --no-deps --wheel-dir=/w/wheels -r requirements.txt # 阶段 2:runtime FROM python:3.10-slim-bookworm # 安装运行期依赖(espeak-ng 等) RUN sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list && \ apt-get update && \ apt-get install -y --no-install-recommends libespeak-ng-dev && \ rm -rf /var/lib/apt/lists/* WORKDIR /app # 把 builder 产出的轮子一次性装进来 COPY --from=builder /w/wheels /wheels RUN pip install --no-index --find-links=/wheels ChatTTS && \ rm -rf /wheels COPY . /app CMD ["python", "app.py"]构建 & 运行:
# x86_64 docker buildx build --platform linux/amd64 -t chatts:slim . # ARM64(M1 开发板) docker buildx build --platform linux/arm64 -t chatts:slim .实测在 4C8G 云主机上,第二次 build(只改业务代码)耗时 18 s,真正做到了“编译一次、到处运行”。
五、避坑指南:证书、glibc、内存三连击
证书错误
CERTIFICATE_VERIFY_FAILED- 公司网关替换证书,pip 默认不信任
- 临时解决:在 pip.conf 加
trusted-host = *(仅内网) - 根治:让运维把根证书加到系统 store,然后
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
glibc 版本冲突
version 'GLIBX_2.29' not found- manylinux_2_31 轮子需要更高 glibc,而 CentOS 7 只有 2.17
- 解决:升级系统或改用 manylinux2014 轮子;容器化最省心,直接 bookworm 基础镜像
编译阶段 OOM(尤其 tokenizers)
- 限制并行度:
export CMAKE_BUILD_PARALLEL_LEVEL=2 - 加 swap:阿里云轻量实例 2 G 内存也能编过去
- 直接放弃编译,回退到
--prefer-binary或 Docker 交叉编
- 限制并行度:
六、还能再快吗?一个开放问题
目前三条路已经让 90% 的同学脱离苦海,但“等待”依旧黑箱:pip 的日志只滚动包名,看不到剩余时间。能否给 ChatTTS 写个“安装进度可视化”小工具?
- 思路 1:解析 pip JSON 日志,实时计算总轮子大小与已下载字节,输出 tqdm 进度条
- 思路 2:用 aiohttp 搭本地代理,劫持 PyPI 响应,在 HTTP chunk 里插桩进度事件
- 思路 3:直接给 pip 提 PR,支持
--progress=gui,官方认可后所有包受益
如果你折腾出了新花样,欢迎留言交流,一起把“15 min 安装”彻底扫进历史。