1. WSL2 里跑 libtorch 推理为什么总在第一步卡住如果你在 WSL2 里用 C 加载 PyTorch 模型大概率会遇到这么一串报错undefined reference to torch::jit::load、cannot find -ltorch、或者 CMake 配置阶段直接告诉你TorchConfig.cmake not found。这些问题的根源往往不是代码写错了而是环境路径、ABI 版本、模型导出方式三件事没对齐。这篇要聊的场景很具体在 WSL2 的 Linux 环境里用 libtorch 1.10.0-CPU 去加载一个 PyTorch 1.12.1 训练并导出的模型走完从模型转换、CMake 配置、编译链接到 CPU 推理验证的完整链路。同时把 TaoToken 的统一 Key 和 API 通道接进这套 AI 工具链让模型调试、代码补全、报错排查这些环节能在一个入口里完成。适合谁看已经在 WSL2 里写过 C、手里有.pth模型、想把它变成可执行推理程序的人。libtorch 和 PyTorch 的版本关系这里要强调一下官方建议版本对应但实际项目里经常出现 PyTorch 高版本、libtorch 低版本的情况。我这次就是 PyTorch 1.12.1 导出、libtorch 1.10.0 加载属于「高导低载」能跑通但导出方式必须用torch.jit.trace而不是直接torch.save整个模型对象。下面按步骤拆开讲。2. TaoToken 前置统一 Key 接入 AI 工具链在开始编译之前先把工具链的「入口」理清楚。TaoToken 提供的是一个统一的 API 通道官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 。它的作用是让你用同一个 Key 去调用不同模型省得在多个平台之间来回切换配置。对这篇的场景来说TaoToken 主要用在两个地方一是模型导出阶段如果torch.jit.trace报错可以把报错信息丢给模型对话去分析二是 C 编译阶段CMake 或链接报错时用 Coding Plan 做长上下文排查。你不需要在 WSL2 里装额外的客户端直接用 curl 或 Python 请求就行。先拿 Key。进入控制台创建 API Key地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。创建完之后复制那串sk-开头的字符串后面配置里会用到。如果你只是想先验证模型能不能通可以直接用模型对话页面测试地址是 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。配置方式很简单在 WSL2 的 shell 里设一个环境变量export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api如果你习惯用config.toml管理可以建一个~/.taotoken/config.toml[api] base_url https://taotoken.net/api api_key sk-你的key timeout 60 [model] default claude-sonnet这个配置文件的作用是给后续的脚本和工具链一个统一读取入口。比如你写个 Python 脚本去调模型分析 trace 报错直接读这个 toml 就行不用每次硬编码 Key。注意不要把 Key 提交到 git建议加进.gitignore。3. 可复制配置从 .pth 到 .pt 再到可执行文件3.1 模型导出trace 而不是 savePyTorch 1.12.1 训练完的模型如果直接torch.save(model, saved_model.pth)libtorch 1.10.0 是加载不了的因为整个模型对象序列化依赖 Python 类定义。正确做法是用torch.jit.trace导出成 TorchScript。import torch import torch.nn as nn import numpy as np class Net(nn.Module): def __init__(self, n_features): super(Net, self).__init__() self.l1 nn.Linear(n_features, 32) self.l2 nn.ReLU() self.l3 nn.BatchNorm1d(32) self.l4 nn.Linear(32, 64) self.l5 nn.ReLU() self.l6 nn.BatchNorm1d(64) self.l7 nn.Linear(64, 128) self.l8 nn.ReLU() self.l9 nn.BatchNorm1d(128) self.l10 nn.Linear(128, 64) self.l11 nn.ReLU() self.l12 nn.BatchNorm1d(64) self.l13 nn.Linear(64, 32) self.l14 nn.ReLU() self.l15 nn.BatchNorm1d(32) self.l16 nn.Linear(32, 1) def forward(self, inputs): out self.l1(inputs) out self.l2(out) out self.l3(out) out self.l4(out) out self.l5(out) out self.l6(out) out self.l7(out) out self.l8(out) out self.l9(out) out self.l10(out) out self.l11(out) out self.l12(out) out self.l13(out) out self.l14(out) out self.l15(out) out self.l16(out) return out device torch.device(cpu) model Net(n_features24) model.load_state_dict(torch.load(saved_model.pth, map_locationdevice)) model.eval() # 关键trace 时输入 shape 要和推理时一致 example_input torch.randn(1, 24) traced torch.jit.trace(model, example_input) traced.save(model.pt) print(export done)这里有个坑如果forward里有torch.from_numpy这种把 numpy 转 tensor 的操作trace 会失败。导出前把这类代码注释掉输入统一用 tensor。3.2 libtorch 下载与解压libtorch 1.10.0-CPU 的包名是libtorch-cxx11-abi-shared-with-deps-1.10.0cpu.zip。在 WSL2 里建目录解压mkdir -p ~/libtorch cd ~/libtorch unzip libtorch-cxx11-abi-shared-with-deps-1.10.0cpu.zip -d ~/libtorch解压后目录结构是~/libtorch/libtorch/{bin,include,lib,share}。注意share/cmake/Torch这个路径CMake 找的就是它。3.3 main.cpp 推理代码#include torch/script.h #include iostream #include memory #include chrono int main(int argc, const char* argv[]) { if (argc ! 2) { std::cerr usage: main path-to-exported-script-module\n; return -1; } torch::Device device(torch::kCPU); torch::jit::script::Module module torch::jit::load(argv[1]); module.to(device); module.eval(); std::vectortorch::jit::IValue inputs; inputs.push_back(torch::ones({1, 24}).to(device)); auto begin std::chrono::high_resolution_clock::now(); at::Tensor output module.forward(inputs).toTensor(); auto end std::chrono::high_resolution_clock::now(); auto elapsed std::chrono::duration_caststd::chrono::nanoseconds(end - begin); printf(Time measured: %.6f seconds.\n, elapsed.count() * 1e-9); std::cout Output: output.itemfloat() \n; std::cout ok\n; return 0; }3.4 CMakeLists.txt 骨架cmake_minimum_required(VERSION 3.12 FATAL_ERROR) project(main) find_package(Torch REQUIRED) set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}) add_executable(main main.cpp) target_compile_features(main PUBLIC cxx_range_for) target_link_libraries(main ${TORCH_LIBRARIES}) set_property(TARGET main PROPERTY CXX_STANDARD 14)3.5 编译与运行mkdir -p build cd build cmake -DCMAKE_PREFIX_PATH$HOME/libtorch/libtorch .. make -j4 ./main ../model.pt如果find_package(Torch)报找不到检查CMAKE_PREFIX_PATH是否指向libtorch根目录里面要有share/cmake/Torch/TorchConfig.cmake。4. 验证请求一次可复现的 CPU 推理编译成功后运行./main ../model.pt预期输出类似Time measured: 0.000123 seconds. Output: 0.4523 ok这个Output是模型对全 1 输入的预测值。为了确认结果可复现可以在 Python 侧用同样的输入跑一遍 trace 后的模型import torch ts torch.jit.load(model.pt) out ts(torch.ones(1, 24)) print(out.item())两边数值应该一致浮点误差范围内。如果 C 侧输出和 Python 侧差很多大概率是输入 shape 或 dtype 不一致检查torch::ones({1, 24})是否和 trace 时的torch.randn(1, 24)维度匹配。TaoToken 在这个环节的用法把 C 运行输出和 Python 输出一起贴到模型对话里让它帮你比对数值差异原因。地址是 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。如果是链接阶段的报错用 Coding Plan 做长上下文分析更合适入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。5. 本篇常见错排查5.1 undefined reference to torch::jit::load链接阶段报这个通常是target_link_libraries没写对或者TORCH_LIBRARIES为空。检查find_package(Torch REQUIRED)是否成功可以在 CMakeLists 里加一行message(STATUS Torch libs: ${TORCH_LIBRARIES})看输出。5.2 ABI 不匹配导致崩溃libtorch 有cxx11-abi和pre-cxx11-abi两个版本。如果你用 GCC 5 以上编译选cxx11-abi。选错了会在运行时报undefined symbol或直接 segfault。WSL2 默认 GCC 版本一般够用gcc --version确认。5.3 trace 报错Expected a value of type Tensor这是forward里有 numpy 操作导致的。把torch.from_numpy(inputs)这类代码删掉输入直接用 tensor。如果模型必须接受 numpy就在 Python 侧包一层trace 外层 wrapper。5.4 运行时报找不到 libtorch.so编译通过但运行./main时报error while loading shared libraries: libtorch.so。解决方式是设LD_LIBRARY_PATHexport LD_LIBRARY_PATH$HOME/libtorch/libtorch/lib:$LD_LIBRARY_PATH或者把 libtorch 的 lib 路径写进/etc/ld.so.conf.d/再ldconfig。5.5 模型输出 NaNCPU 推理出现 NaN常见原因是 BatchNorm 在 eval 模式下统计量不对。确认导出前调用了model.eval()并且 trace 时模型处于 eval 状态。如果训练时 BatchNorm 的track_running_stats是 False导出后也会有问题。6. 把 Key 和推理链路固定下来整套流程跑通之后建议把几个东西固定成脚本模型导出脚本、CMake 配置命令、运行时的环境变量。TaoToken 的 Key 放在config.toml里统一管理后续不管是排查 trace 报错还是分析链接日志都从同一个入口走。API Keys 管理页面在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。如果你后续要把这套推理程序接进更大的 C 工程或者用 Claude Code 做自动化构建可以走 Coding Plan 那条线把编译、测试、报错分析串成一个长上下文任务。实测下来把CMAKE_PREFIX_PATH和LD_LIBRARY_PATH写进 shell 的 rc 文件比每次手动 export 省事得多。
企业数字化 ERP 产品动态
相关推荐
NewAPI网关部署与企业Token监管实操指南:TaoToken统一Key接入配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 19:54:54
自己做公司网站完整流程:从0到1的实战复盘 自己做公司网站完整流程:从0到1的实战复盘 自己不会代码想做网站,是不是觉得这事儿像天方夜谭?别急,十年前我也这么想,直到我接手了一个小型制造企业官网项目,才彻底搞明白这背后的门道。很多人一听到“建站”就想到找外包,报价动辄几万,改个按钮还… · 2026/9/27 19:54:48
Poki免费游戏网站评测:免下载HTML5网页游戏平台,家长可控的休闲游戏宝库 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 20:29:09
ComfyUI+QwenImageEdit实现任意场景人物一致性写真工作流 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 20:29:09
3个坑教你避坑:学校网站建设作用与最佳实践 3个坑教你避坑:学校网站建设作用与最佳实践 找过建站公司的朋友都知道,最怕的就是报价单上写个“面议”,聊完发现比预算高出一大截,或者功能缩水得厉害。很多学校负责人在咨询时,第一反应就是担心被坑高价,花了几万块最后只得到一个能看不能用的网站。… · 2026/9/27 20:29:09
高校无线校园WLAN组网方案:认证、射频与接入层配置实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 20:29:03
RS485与LoRa参数调试工具:协议验证自动化实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 20:29:03
稚嫩的初中生:青春期学习习惯与亲子沟通指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 20:29:03
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01