公司动态

PyTorch还是TensorFlow?深度学习新手选型与环境搭建实战指南

📅 2026/8/31 15:47:31
PyTorch还是TensorFlow?深度学习新手选型与环境搭建实战指南
深度学习入门最常被问到的几个问题里一定包含“应该先学 PyTorch 还是 TensorFlow”。这个问题表面上只是两个框架二选一背后实际对应三个更具体的问题你准备用深度学习解决什么任务你当前的机器能把哪个环境先跑通以及你希望在多大程度上控制模型的训练过程。如果只盯着“哪个教程评价更高”很容易陷入反复比较却始终没有动手的循环。下面会沿着一条可复现的路线展开先理解两个框架的设计差异再准备环境接着用同一个最小分类任务跑通两个框架最后聊一聊工程部署、常见问题和选型决策。这套流程走完你至少能自己判断该从哪里开始。1. 先搞清楚框架之争在争什么1.1 为什么新人会卡在这个问题上深度学习框架本质上做的事情是把网络结构定义成可计算的图自动计算梯度并利用 GPU 加速训练。PyTorch 和 TensorFlow 在早期分别代表了两种设计思路动态计算图和静态计算图。PyTorch 在代码运行时逐行构建计算图写起来接近普通 Python 程序调试时可以直接打印中间张量TensorFlow 1.x 则更像先定义一张完整计算图再放到会话中执行好处是部署时可以整体优化坏处是调试不够直观。TensorFlow 2.0 之后默认开启了 eager 模式也提供了 Keras 高层 API因此两个框架在入门体验上的差距已经明显缩小。不过它们设计时的定位差异仍然会体现在后续的代码风格和部署生态里。很多课程、论文复现、竞赛代码默认使用 PyTorch而不少企业级平台、移动端和嵌入式方案仍然基于 TensorFlow 或在其生态上扩展。新人会被这个问题困住通常不是因为两个框架真的无法选择而是因为缺少一个“先跑通最小模型”的目标。在没有目标的情况下框架对比、教程评价、资料多少都会变成噪音。更好的方式是先把问题缩小到我的第一个深度学习程序要在哪个环境里跑起来要完成一个什么样的任务。1.2 PyTorch 与 TensorFlow 的核心定位差异可以把差异理解为“编程体验”和“部署生态”的不同侧重点而不是单纯的优劣。PyTorch 的默认工作流非常接近研究代码你需要自己写训练循环自己控制 batch 的迭代自己调用loss.backward()计算梯度。这套过程对初学者其实很有价值因为自动求导虽然省事但你不应该完全不知道梯度从哪里来。TensorFlow 的 Keras 高层 API 则把训练过程封装得更彻底。一个model.fit()可以完成数据迭代、梯度计算、参数更新和验证集评估代码量更少适合快速验证。但封装度高也意味着出问题时排查链路更长尤其是当模型行为不符合预期时你需要在封装层里找到对应的回调或执行细节。下面的表格可以做一个快速对照比较维度PyTorchTensorFlow默认编程风格命令式逐行构建动态图命令式 Keras 高层 API也保留静态图部署能力模型定义继承nn.Module实现forward常用Sequential或函数式 API 堆叠层训练过程手动 for 循环暴露梯度计算细节compilefit高层封装调试方式可以直接打印中间张量与 Python 调试器配合自然也可以打印但高层封装下部分堆栈较绕部署生态TorchScript、ONNX、PyTorch ServeSavedModel、TF Serving、TFLite、TF.js典型场景论文复现、课程实验、算法验证、竞赛企业服务、移动端、已有 TensorFlow 基础设施这张表不是告诉你“必须学哪个”而是告诉你“哪个更匹配你现在的场景”。如果你是学生需要尽快复现论文或完成课程作业PyTorch 的默认工作流通常更接近你要看的代码。如果你所在团队已经有完整的 TensorFlow 服务链路或者你准备做移动端模型部署TensorFlow 的生态更值得优先熟悉。1.3 教程数量和“公认”并不等于可复现网络上很多标题会写“公认最好”“全套教程”“一网打尽”这类说法能吸引点击但很难作为技术选型依据。教程的真正价值取决于三点环境是否可复现代码能否直接运行报错之后能否继续往下排查。一个教程如果只是概念讲得漂亮却要求读者使用已经过时的 API或者安装步骤隐藏了一堆环境假设那么它对你完成第一个项目的帮助很有限。更务实的做法是选择一套语言简洁、版本明确、代码能形成最小闭环的教程然后在自己的机器上一步步操作。遇到报错不要第一时间怀疑资料先检查环境路径、依赖版本和输入数据是否符合预期。框架的选择始终服务于一件事让你能尽快把想法转化成可运行、可验证的程序。2. 学习框架之前的共识环境准备比框架本身更容易卡住2.1 先确定硬件和系统深度学习环境可以分为三类纯 CPU 环境、带 NVIDIA GPU 的 PC/服务器、嵌入式平台如 Jetson。CPU 环境完全可以用于学习最小模型比如后面要写的两层全连接网络训练时间可以接受GPU 环境能明显加速训练但多出来的驱动、CUDA、cuDNN 匹配问题往往比框架安装本身更耗时Jetson 平台则依赖 JetPack 版本不能直接照搬 PC 的 pip 安装命令。环境类型适合场景主要风险CPU语法学习、最小示例、验证代码流程大模型训练很慢NVIDIA GPU常规深度学习实验和业务训练CUDA 版本、显卡驱动、框架 wheel 不匹配Jetson / 嵌入式边缘推理、机器人、嵌入式视觉PyTorch 版本与 JetPack 强绑定实际项目中很多新手并不是不会写模型而是把一整天时间耗在安装和依赖上。所以环境准备阶段一定要慢下来每一步都验证之后再进入下一步。2.2 用虚拟环境隔离依赖不同项目依赖的 Python 版本、CUDA 版本和框架版本可能不一样。不要把深度学习依赖直接装到系统 Python 里否则项目一多很快就会冲突。推荐在项目目录下创建虚拟环境python -m venv dl_envLinux/macOS 激活source dl_env/bin/activateWindows 激活dl_env\Scripts\activate激活后先升级 pippython -m pip install --upgrade pip创建虚拟环境的目的是让 PyTorch、TensorFlow、NumPy 等依赖互相隔离。每个实验项目使用独立环境出现问题时可以直接删除重建不会影响其他项目。2.3 PyTorch 与 TensorFlow 的安装命令PyTorch 官方安装页会根据你的操作系统、包管理工具和 CUDA 版本生成命令。这里需要先知道两个概念显卡驱动和 CUDA Toolkit。驱动层面可以用nvidia-smi查看PyTorch 的 wheel 包通常会自带对应 CUDA 运行库但需要和你的驱动版本兼容。如果是纯 CPU 环境可以安装 CPU 版本pip install torch torchvision torchaudio如果需要 GPU 版本通常使用官方 index-url。下面的命令是常用写法实际版本号以官方页面为准pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121TensorFlow 的安装相对直接。在 Linux 上通常一条命令即可pip install tensorflow如果只需要 CPU 版本可以安装tensorflow-cpu。要注意 TensorFlow 2.18 这类较新版本对 Python 版本有明确要求安装前先看官方发布说明。不要凭记忆选版本尤其是旧教程里的安装命令很可能对应的是已不再维护的版本。2.4 安装后的验证清单安装完成后不要急着写模型。先做几个最小验证确认框架确实能正常工作。PyTorch 验证import torch print(torch.__version__) print(torch.cuda.is_available())如果可以识别 GPU再打印设备名称if torch.cuda.is_available(): print(torch.cuda.get_device_name(0))TensorFlow 验证import tensorflow as tf print(tf.__version__) print(tf.config.list_physical_devices(GPU))验证时不要只看“能 import”还要看版本号是否符合预期GPU 是否真的被识别。可以跑一个很小的矩阵乘法确认没有隐藏的链接错误。如果版本号带cu字样说明这是带 CUDA 支持的构建如果安装了 CPU 版本torch.cuda.is_available()返回False是正常的不需要继续排查 GPU。注意不要只验证程序能启动还要验证输入、输出、异常分支和日志是否符合预期。环境验证最重要的是把“当前环境到底是什么”记录下来方便后面排错。3. 用最小项目跑通两个框架先不要追求复杂模型3.1 为什么选择同一个最小分类任务如果你一上来就去搭 ResNet 或 Transformer很容易把“框架语法”和“模型原理”混在一起。模型结构复杂时你很难判断报错原因是网络设计问题、数据 shape 问题还是框架 API 使用问题。最小任务只需要用两层全连接网络把一组二分类数据分开但已经覆盖了张量创建、数据加载、模型定义、损失计算、梯度更新、验证评估这些关键环节。为了公平对比两个框架使用同一个数据集、同一个网络结构、同一个优化器配置。3.2 用 PyTorch 完成最小训练示例先准备数据和数据加载器import torch import torch.nn as nn from torch.utils.data import DataLoader, TensorDataset from sklearn.datasets import make_moons from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler X, y make_moons(n_samples1000, noise0.2, random_state42) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 ) scaler StandardScaler() X_train scaler.fit_transform(X_train) X_test scaler.transform(X_test) X_train_t torch.tensor(X_train, dtypetorch.float32) y_train_t torch.tensor(y_train, dtypetorch.long) X_test_t torch.tensor(X_test, dtypetorch.float32) y_test_t torch.tensor(y_test, dtypetorch.long) train_ds TensorDataset(X_train_t, y_train_t) train_loader DataLoader(train_ds, batch_size32, shuffleTrue)定义模型class MLP(nn.Module): def __init__(self): super().__init__() self.net nn.Sequential( nn.Linear(2, 16), nn.ReLU(), nn.Linear(16, 2) ) def forward(self, x): return self.net(x) model MLP() loss_fn nn.CrossEntropyLoss() optimizer torch.optim.Adam(model.parameters(), lr0.01)训练循环for epoch in range(20): model.train() total_loss 0.0 for xb, yb in train_loader: optimizer.zero_grad() out model(xb) loss loss_fn(out, yb) loss.backward() optimizer.step() total_loss loss.item() * xb.size(0) avg_loss total_loss / len(X_train_t) print(fepoch {epoch}, loss {avg_loss:.4f})测试评估model.eval() with torch.no_grad(): pred model(X_test_t).argmax(dim1) acc (pred y_test_t).float().mean().item() print(test acc:, acc)PyTorch 的特点在这段代码里体现得很明显训练循环是显式的梯度清零、前向、反向、参数更新都在你自己的控制范围内。loss.backward()是自动求导的核心它会根据计算图反向计算每个参数的梯度然后由optimizer.step()更新参数。推理阶段通过model.eval()切换模型状态用torch.no_grad()关闭梯度计算节省内存和耗时。3.3 用 TensorFlow 完成最小训练示例TensorFlow 使用 Keras 高层 API同一个任务的代码明显更短import tensorflow as tf from sklearn.datasets import make_moons from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler X, y make_moons(n_samples1000, noise0.2, random_state42) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 ) scaler StandardScaler() X_train scaler.fit_transform(X_train) X_test scaler.transform(X_test) model tf.keras.Sequential([ tf.keras.layers.Dense(16, activationrelu, input_shape(2,)), tf.keras.layers.Dense(2, activationsoftmax) ]) model.compile( optimizertf.keras.optimizers.Adam(learning_rate0.01), losstf.keras.losses.SparseCategoricalCrossentropy(), metrics[accuracy] ) model.fit(X_train, y_train, epochs20, batch_size32, validation_split0.2, verbose2) loss, acc model.evaluate(X_test, y_test, verbose0) print(test acc:, acc)TensorFlow 通过compile指定优化器、损失函数和评估指标通过fit完成训练。validation_split0.2表示从训练数据里再拿 20% 作为验证集。这里要说明一点如果同时使用validation_split和单独的测试集验证集和测试集是两个不同概念。验证集用于观察训练过程中的泛化情况测试集用于最终评估。SparseCategoricalCrossentropy适合标签是整数编号的分类任务如果标签是 one-hot 编码则应使用CategoricalCrossentropy。这是新手很容易踩的问题。3.4 两个框架在同一个任务上的差异环节PyTorchTensorFlow/Keras数据加载使用DatasetDataLoader可以直接传入 NumPy 数组也可以使用tf.data模型定义继承nn.Module手写forward使用Sequential堆叠层训练入口自己写 for 循环model.fit封装训练梯度计算显式调用loss.backward()compile和fit中隐式完成推理评估model.eval()no_gradmodel.evaluate/predict同样是两层全连接网络PyTorch 更接近“教你理解神经网络如何训练”TensorFlow 的 Keras API 更接近“快速得到结果”。对深度学习入门来说两种路线都有价值。我的建议是如果时间有限先按一个框架跑通但至少要把 PyTorch 里手动训练的这几个步骤理解清楚因为它能帮你建立对训练循环的正确直觉。4. 从第一个最小项目到真实项目训练、验证、部署和监控4.1 学习环境能跑通之后生产环境还要补什么本地 Jupyter Notebook 里模型能跑不等于生产环境可用。实际项目还要补充这些能力配置外置化训练参数、数据路径、模型路径不要写死在代码里通过环境变量或配置文件管理。日志与监控记录训练 loss、验证指标、资源占用以及推理阶段的延迟和错误率。模型版本管理模型文件要有版本号训练代码和数据也要能对应到同一个版本。数据校验推理输入数据可能缺失、格式错误需要提前定义校验规则。权限与审计谁访问了模型、谁发起了推理、谁修改了配置生产环境都需要可追溯。回滚方案新模型效果不如旧模型时要能快速切回旧版本。这些能力不一定要在入门阶段全部实现但你应该知道从“跑通最小示例”到“上线一个服务”之间还有很长的工程距离。4.2 模型保存与加载格式训练结束后模型需要持久化。PyTorch 常用的做法是保存state_dicttorch.save(model.state_dict(), mlp.pt)加载时需要先创建同样的模型结构再加载参数model MLP() model.load_state_dict(torch.load(mlp.pt)) model.eval()TensorFlow 的 Keras 模型常用SavedModel格式保存model.save(mlp_savedmodel)加载model tf.keras.models.load_model(mlp_savedmodel)如果要在不同框架或不同运行时之间迁移模型ONNX 是一个常见的中转格式。PyTorch 导出 ONNX 的方式如下dummy_input torch.randn(1, 2) torch.onnx.export( model, dummy_input, mlp.onnx, input_names[input], output_names[output] )ONNX 模型可以由 ONNX Runtime 加载也可以继续转换到其他推理引擎。需要注意的是ONNX 不是万能格式一些自定义算子可能无法完整转换。落地前要针对目标推理引擎做充分验证。4.3 部署场景怎么选部署选型更多取决于运行环境部署场景常用方案Python 服务PyTorch 可用 TorchScript、ONNX RuntimeTensorFlow 可用 SavedModel TF Serving移动端TensorFlow Lite 较成熟PyTorch 也有移动端方案但生态相对少浏览器端TensorFlow.js 是常见选择Jetson / 嵌入式通常使用 TensorRT 或 ONNX Runtime版本需匹配 JetPack嵌入式场景尤其要注意版本绑定。比如 Jetson 的 JetPack 6.2.2 支持哪些 PyTorch 版本、哪些 CUDA 版本必须以 NVIDIA 官方支持矩阵为准。不要看到一篇博客说“这样安装成功”就直接照抄先确认对方的 JetPack、Python、PyTorch 版本和你的环境是否一致。4.4 框架之外同样重要的基础知识框架只是工具底层知识仍然很关键。入门阶段不必去啃完整数学推导但至少要理解什么是张量什么是梯度下降损失函数怎样衡量预测和真实值的差距反向传播为什么能让参数更新过拟合和欠拟合有什么区别。后面学习 CNN 时要能说清楚卷积、池化之后张量尺寸为什么变化学习 Transformer 时要能理解注意力机制和输入序列的关系。如果这些基础不补遇到报错时你不知道该从模型结构、数据 shape、还是框架 API 三个方向去排查。正确的顺序是先用最小模型建立框架手感再回到深度学习基础补原理最后再上复杂模型。5. 常见问题排查安装失败、GPU 不生效、版本不匹配5.1 PyTorch 安装后torch.cuda.is_available()返回 False现象import torch print(torch.cuda.is_available()) # False可能原因安装的是 CPU 版本。显卡驱动版本过旧与 PyTorch 自带的 CUDA 运行库不兼容。系统没有识别到 NVIDIA 显卡。检查方式nvidia-smi如果命令能输出显卡和驱动信息说明驱动层面正常。接着查看 PyTorch 构建信息print(torch.__version__)如果版本号没有cu后缀说明是 CPU 版本。需要按官方 index-url 重新安装 GPU 版本。安装前在https://download.pytorch.org/whl/下选择与驱动兼容的 CUDA 版本。注意不要只对着教程抄安装命令要先确认本机 CUDA 环境再选 index-url。GPU 版 PyTorch 对驱动版本有最低要求驱动太老会导致程序运行时报 CUDA 初始化失败。5.2 TensorFlow 识别不到 GPU现象import tensorflow as tf print(tf.config.list_physical_devices(GPU)) # []可能原因安装了tensorflow-cpu。CUDA、cuDNN 版本与 TensorFlow 版本不匹配。在一个没有 GPU 的环境中运行。检查方式先确认安装的是哪个包pip show tensorflow再确认系统是否能识别显卡nvidia-smiTensorFlow 2.x 对 CUDA 和 cuDNN 版本有明确要求需要查看官方兼容列表。如果版本不匹配推荐创建一个新的虚拟环境按官方要求安装对应版本不要在同一环境里反复覆盖依赖。5.3 Ubuntu 驱动安装后nvidia-smi没有反应现象在 Ubuntu 22.04 或 24.04 上安装驱动后执行nvidia-smi提示找不到命令或者显示 GPU 在但训练时仍然无法使用 GPU。可能原因安装了驱动但没有重启系统。系统仍在使用开源的 Nouveau 驱动和 NVIDIA 驱动冲突。Secure Boot 未配置内核模块未能加载。驱动安装命令不完整只装了部分组件。检查方式nvidia-smi lsmod | grep nouveau dmesg | grep -i nvidia如果lsmod输出有nouveau说明开源驱动还在占用显卡。不同发行版屏蔽 Nouveau 的方式不同需要按照当前系统版本的官方文档操作。如果dmesg里出现签名错误则需要处理 Secure Boot 相关配置。不要为了解决这个问题去修改系统安全配置之外的东西按官方文档来最稳妥。5.4 Jetson 等嵌入式平台的 PyTorch 版本选择Jetson 的软件栈和普通 PC 差异很大。JetPack 版本决定 CUDA、cuDNN、TensorRT 的可用版本PyTorch 必须使用对应版本的预编译 wheel 或官方容器。如果你在 Jetson 上直接执行普通 PC 的 pip 安装命令通常会得到不兼容的包甚至无法 import。正确做法是先确认 JetPack 版本例如 JetPack 6.2.2再从 NVIDIA 官方支持矩阵或官方容器源中找到匹配的 PyTorch 版本。不要仅凭“某论坛说能装”来安装版本差一个主版本可能就会导致训练和推理行为不一致。5.5 环境冲突排查顺序遇到环境问题建议严格按下面的顺序排查当前命令是否在正确的虚拟环境里执行输入是否有拼写错误。文件路径和命名是否正确pip show torch、pip show tensorflow确认安装位置。依赖版本是否与操作系统、Python 版本、CUDA 版本匹配。配置是否真的生效环境变量、配置文件修改后是否需要重启。驱动和硬件状态nvidia-smi是最直接的检查命令。日志是否出现明确异常把完整错误堆栈贴到搜索引擎优先看官方 Issue。问题现象常见原因检查方式处理建议torch.cuda.is_available() 为 False装成 CPU 版本查看 torch.version是否有 cu按官方 index-url 重装TF 无法识别 GPU装了 tensorflow-cpu 或 CUDA 版本不匹配pip show tensorflownvidia-smi查看官方兼容矩阵并重建环境Ubuntu 装驱动后无反应未重启或 Nouveau 冲突lsmod、dmesg按发行版官方文档处理Jetson 上安装失败未匹配 JetPack 版本查看 JetPack 和官方支持矩阵使用官方预编译 wheel 或容器6. 决策清单和下一步学习路径6.1 用一张表辅助决定先学哪个框架你的场景优先建议在校学生需要复现论文或完成课程作业PyTorch课程或项目已经指定框架先按指定框架来不要中途换企业后端已有 TensorFlow 服务TensorFlow准备做移动端模型部署TensorFlow Lite 生态更成熟可优先 TensorFlow目标是嵌入式 Jetson 开发先看 JetPack 支持矩阵再决定完全新手想最快看到模型效果TensorFlow Keras 的 fit 更快但建议之后用 PyTorch 补一遍训练循环这张表只是起点。实际工作中团队和项目约束往往比个人偏好更重要。如果你所在团队用 PyTorch那么你对 TensorFlow 的熟悉可以慢慢补反之亦然。学会一个框架后迁移到另一个框架的成本远低于从零开始。6.2 最少必要学习路径建议按下面的顺序走不要在任意一步求快掌握 Python 和 NumPy 基础数组操作、函数、类、切片、广播。理解深度学习的核心概念梯度下降、反向传播、损失函数、过拟合。用最小模型跑通框架数据加载、模型构建、训练、评估、保存和加载。学习数据管线PyTorch 的Dataset/DataLoaderTensorFlow 的tf.data。从 MLP 过渡到 CNN重点理解卷积和池化后的张量 shape 变化。再进入序列模型和 Transformer不要跳过前面的基础。最后补工程化能力模型管理、部署、日志、监控、回滚。每一步都要求能运行、能复现、能解释。只把代码跑通但不理解每一行在做什么遇到真实问题时还是会卡住。6.3 容易继续踩的坑坑一在 CPU 环境里安装了 GPU 版本但没有显卡驱动。程序能跑但训练慢偶尔还会出现 CUDA 初始化失败。安装前先确认nvidia-smi是否可用再选对应安装命令。坑二照着过时教程写 API。比如 TensorFlow 1.x 的Session、placeholder写法在 2.x 中已经不再推荐PyTorch 某些接口也经历过变动。看到旧教程时先看发布时间和版本号再决定是否参考。坑三只背框架 API不关注数据 shape。CNN 中一个常见的报错是卷积或池化后张量维度不匹配。这时候应该手动计算一下输入从(batch_size, channels, height, width)到输出 shape 的变化而不是盲目加Flatten或调整全连接层尺寸。框架不会替你解决模型结构设计错误。6.4 让第一个项目成为你的判断基准从“选框架”到“跑通第一个模型”真正有效的动作是动手。即使最后你选择的框架被证明不适合某个任务你也会在这个过程中学到环境排查、数据准备、模型调试的能力这些能力可以迁移到任何框架上。建议今天只做一件事按第 2 节的内容创建虚拟环境安装一个框架跑通第 3 节的最小分类示例然后把运行结果和版本信息保存成一份环境记录文档。下一个项目开始时你会感谢这份记录。它不是完美的选择但比继续比较十个教程要有效得多。