90%以上情况降级到protobuf==3.20.3即可解决,因其精准兼容TensorFlow旧代码对builder模块的路径引用,且避开3.21.0+移除internal.builder及4.x不兼容问题,同时需彻底清理残留文件、匹配protoc版本并避免多源混装。

直接结论:90%以上情况,降级到 protobuf==3.20.3 就能跑通,但必须确保没有残留旧版本、protoc 版本匹配、且不混用多个 protobuf 安装源。
为什么 ImportError: cannot import name 'builder' from 'google.protobuf.internal' 一出现就该怀疑 protobuf 版本?
这个错误不是“没装 protobuf”,而是你装了 protobuf>=4.0 或 protobuf==3.21.0+,而 TensorFlow(尤其是 object_detection 等子模块)生成的 _pb2.py 文件仍硬编码依赖旧路径。Protobuf 3.20.0 起把 builder 移到了 google.protobuf 根命名空间,google.protobuf.internal 里真没了。
常见触发场景:
- 用
pip install tensorflow==2.10后自动拉入protobuf==4.x(新版 pip 默认倾向高版本) - 先装了
grpcio或paddlepaddle,它们自带 protobuf 4.x 运行时,再装 TF 时 pip 没强制降级 - conda 环境里混用了 pip 安装的 protobuf 和 conda-forge 的 protobuf
降级前必须清理干净:残留的 .dist-info 和 __pycache__ 是静默失败元凶
只执行 pip uninstall protobuf 不够——pip 可能只删主模块,但 site-packages/google/protobuf/ 下的 __pycache__ 目录或残留的 protobuf-3.19.0.dist-info 会被 Python 自动加载,导致你以为降级成功,实际还在用旧符号。
立即学习“Python免费学习笔记(深入)”;
安全清理步骤:
- 运行
pip uninstall protobuf -y - 手动进入
python -c "import site; print(site.getsitepackages())"输出的路径,找到google/protobuf/和同级的protobuf-*.dist-info文件夹,全部删掉 - 检查
pip list | grep protobuf输出为空,再装新版本
装 protobuf==3.20.3 后仍报 TypeError: Descriptors cannot be created directly 怎么办?
这说明你本地的 protoc 编译器版本和运行时 protobuf 版本错位。比如用 protoc 24.x 编译了 .proto 文件,但运行时是 protobuf 3.20.3,二者 ABI 不兼容。
验证与修复:
- 查 protoc 版本:
protoc --version(输出类似libprotoc 21.12) - 查 python protobuf 版本:
pip show protobuf(应为3.20.3) - 理想匹配:
protoc 21.x→protobuf 3.20.x;protoc 24.x→protobuf 4.21.0+ - 若必须混用,临时加环境变量:
PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python python your_script.py(性能下降 30–40%,仅应急)
虚拟环境里发现两个 protobuf 版本共存?优先用 pipenv 或 venv + requirements.txt 锁死
用 conda activate xxx && pip list | grep protobuf 看到两行输出(如 protobuf 3.20.3 和 protobuf-3.19.5),说明有包通过 setup.py install 或 pip install -e 方式安装了带版本后缀的变体,pip 不认为它是同一包。
可靠锁定方式:
- 新建干净 venv:
python -m venv tf_env && source tf_env/bin/activate(Linux/macOS) - 写死依赖:
echo "protobuf==3.20.3" > requirements.txt && echo "tensorflow==2.10.0" >> requirements.txt - 安装:
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
复杂点在于:TensorFlow 的 _pb2.py 文件是编译期产物,一旦生成就绑定 protobuf 运行时版本;而很多老项目(如 TF Models)的 protos/ 目录下文件没随 Protobuf 升级重生成——所以光换运行时不够,得确认你用的 _pb2.py 是用匹配的 protoc 生成的。


















