首页
/ Langflow 在 macOS Intel (x86_64) + Python 3.13 上 PyTorch Wheel 缺口的根因调查与 PEP 508 平台排除实践

Langflow 在 macOS Intel (x86_64) + Python 3.13 上 PyTorch Wheel 缺口的根因调查与 PEP 508 平台排除实践

2026-09-04 13:25:23作者:殷蕙予

本文基于 Langflow 仓库内的调查文档 TORCH_MACOS_AMD64_PYTHON313_INVESTIGATION.md 展开,完整还原一个典型的跨平台依赖故障:PyTorch 在 2.2.2 之后停止发布 macOS x86_64(Intel)二进制 wheel,而 Python 3.13 在其后才发布,导致“macOS Intel + Python 3.13”这个组合永久性地没有官方 PyTorch 二进制可用,进而在 Langflow 的 test-installation-experimental CI 任务上产生持续性安装失败。读完本文,你将掌握如何用 PEP 508 环境标记(environment markers)在 pyproject.toml 中按平台精确排除依赖、如何理解 uv lockfile 中按平台分裂的 wheel 解析结果,以及如何在 CI 矩阵中用 continue-on-error 与“稳定/实验分层”策略处理平台 EOL(End-of-Life)问题。

一、问题结论先行:这是一个上游永久性缺口,不是 Langflow 的 Bug

调查文档的 TL;DR 给出了明确结论:

  • PyTorch 在 2.2.2 版本之后正式放弃了 macOS x86_64(Intel)的 wheel 构建(废弃里程碑为 PyTorch 2.3,2024 年 3 月);
  • Python 3.13 于 2024 年 10 月发布,晚于上述截止点,因此“macOS x86_64 + Python 3.13”这一组合不存在任何官方 PyTorch wheel
  • 这是一个上游(upstream)的、永久性的支持缺口,不是 Langflow 自身的缺陷
  • 受影响的 CI 任务是运行在 macos-latest-large(AMD64)上的 test-installation-experimental,配合 continue-on-error: true 标记,该失败不阻塞发布,但属于持续性、可预期的失败。

PyTorch macOS x86_64 废弃时间线

事件 时间 说明
PyTorch 社区发起废弃 macOS x86_64 构建的 RFC(issue #114602) 2023 年 11 月 上游决策起点
PyTorch 2.2.2 发布(最后一批 x86_64 macOS wheel) 2024 年 3 月 该版本仅含 cp310cp311cp312 三种 ABI 的 macOS x86_64 wheel
PyTorch 2.3.0 发布(不再包含任何 macOS x86_64 wheel) 2024 年 4 月 x86_64 废弃的正式里程碑
Python 3.13 发布 2024 年 10 月 时间点晚于 PyTorch 放弃 macOS x86_64,缺口自此形成

关键事实是:PyTorch 2.2.2 虽然有 macOS x86_64 的 wheel,但只覆盖 Python 3.10/3.11/3.12,没有 3.13;而 PyTorch 2.3 及以后对 macOS x86_64 平台完全不再发布 wheel。两个事实叠加,封死了“macOS Intel + Python 3.13”的所有官方二进制路径。

二、根因分析:uv 解析器如何“选中”一个无 wheel 的版本

1. uv lockfile 中 torch 的平台分裂

在 macOS x86_64 + Python 3.13 环境下进行依赖解析时,uv lockfile 中的 torch 条目按平台分裂为如下结构(调查文档中的快照):

torch 2.2.2        → Python < 3.13, macOS x86_64  (有 wheel: cp310, cp311, cp312)
torch 2.2.2+cpu    → Python >= 3.13, macOS x86_64  (未列出任何 WHEEL!)
torch 2.10.0       → macOS arm64 (所有 Python 版本)
torch 2.10.0+cpu   → Linux/Windows (所有 Python 版本)

解析器在“macOS x86_64 + Python 3.13”组合下会选中 torch 2.2.2+cpu,但该版本在目标平台上没有任何可用 wheel。安装随即失败——不是依赖冲突,而是“没有兼容二进制可下载”。这类故障的特征是:依赖树本身能解析通过,失败发生在安装(download/unpack)阶段。

2. torch 是如何被 Langflow 拉进依赖树的

langflow 包依赖 langflow-base[complete],其中多个 extras 会传递性地引入 torch。调查文档梳理的依赖链如下:

Extra 依赖链 在 macOS x86_64 上是否已排除
altk agent-lifecycle-toolkit → torch(直接依赖)
altk agent-lifecycle-toolkitsentence-transformers → torch
altk agent-lifecycle-toolkittrlaccelerate → torch
docling doclingdocling-ibm-models → torch 部分(docling 二进制被排除,但 docling-core 未排除)
easyocr easyocr → torch (在 macOS x86_64 上完全排除)
langchain-huggingface langchain-huggingfacesentence-transformers → torch

其中 ALTK(Agent Lifecycle Toolkit)extra 是迫使 torch 在 macOS x86_64 上安装的主要未设防路径——该问题最初正是在 ALTK 链路上被观察到的,但真正的根因是 PyTorch 的平台支持策略。

3. 代码库中已有的同类缓解措施

Langflow 早已对部分 torch 依赖包使用 PEP 508 平台标记做了 macOS x86_64 排除。调查文档引用的当时配置如下:

# src/backend/base/pyproject.toml
docling = [
    "docling-core>=2.36.1,<3.0.0",
    "docling>=2.36.1,<3.0.0; sys_platform != 'darwin' or platform_machine != 'x86_64'",
]
easyocr = ["easyocr>=1.7.2,<2.0.0; sys_platform != 'darwin' or platform_machine != 'x86_64'"]

标记 sys_platform != 'darwin' or platform_machine != 'x86_64' 的语义是:只要不是“darwin 且 x86_64”就安装,即精确命中 Intel Mac 并跳过,对 Apple Silicon(arm64)和所有 Linux/Windows 环境保持完整功能。问题在于 altklangchain-huggingface 当时没有同类排除标记。

4. CI 侧的配套配置

实验性安装测试位于 .github/workflows/cross-platform-test.ymltest-installation-experimental 任务中(见 任务定义):

  • 在包括 macOS AMD64 在内的所有平台上测试较新的 Python 版本;
  • 任务级声明 continue-on-error: true,失败不会阻塞发布流水线;
  • 下游的 test-summary 聚合任务把实验性平台的失败视为“可接受结果”。

当前仓库中该聚合逻辑仍保留:summary 任务对实验性结果有专门的容忍分支(“实验性平台可以失败”),稳定平台则必须全部成功(见 汇总判定)。

三、四个整改选项及其权衡

调查文档给出了四个选项,这里完整保留其配置示例与利弊分析。

选项 A:在 macOS x86_64 上排除所有 torch 依赖 extras(文档推荐)

仿照 easyocr 的既有做法,给所有传递依赖 torch 的 extras 添加平台标记:

# 在 src/backend/base/pyproject.toml 中
altk = ["agent-lifecycle-toolkit~=0.4.4; sys_platform != 'darwin' or platform_machine != 'x86_64'"]
langchain-huggingface = ["langchain-huggingface==0.3.1; sys_platform != 'darwin' or platform_machine != 'x86_64'"]
  • 优点:CI 在所有实验性平台上通过;macOS x86_64 + Python 3.13 用户仍可正常使用 Langflow(只是没有 ALTK/HuggingFace 功能);与既有 docling/easyocr 模式一致。
  • 缺点:降低了 macOS x86_64 的功能可用性;且影响该平台上的所有 Python 版本,而非仅 3.13。

选项 B:Python 版本 + 平台的复合标记

更“外科手术”的方案——只在真正坏掉的那个组合上排除:

altk = ["agent-lifecycle-toolkit~=0.4.4; (sys_platform != 'darwin' or platform_machine != 'x86_64' or python_version < '3.13')"]
  • 优点:macOS x86_64 + Python 3.10–3.12 上的功能完整保留,仅排除坏掉的那个组合。
  • 缺点:标记更复杂;PEP 508 对复合 OR 条件的求值在不同工具链中可能带来兼容性问题。

选项 C:从实验性 CI 矩阵中移除 macOS AMD64(最简)

鉴于 macOS x86_64 是正在退场的平台(Apple 自 2022 年起不再销售 Intel Mac),可直接从 CI 矩阵移除:

# 从实验性矩阵中移除该条目:
# - os: macos
#   arch: amd64
#   runner: macos-latest-large
#   python-version: "3.13"
  • 优点:改动最小(一行);节省 CI 成本(macos-latest-large runner 昂贵);与平台 EOL 的现实一致。
  • 缺点:失去对 macOS x86_64 回归的可见性;仍有部分用户停留在 Intel Mac。

选项 D:维持现状(Status Quo)

实验性任务本就带 continue-on-error: true,test-summary 也将其报告为可接受;该失败是一个已知且已记录的限制。

  • 优点:无需任何代码改动;保持 CI 可见性。
  • 缺点:持续红色的 CI 任务造成告警疲劳(alert fatigue);可能掩盖实验性矩阵中其他真实失败。

文档给出的最终推荐:选项 A + 选项 C 组合

  1. altklangchain-huggingface 添加 macOS x86_64 平台排除标记(选项 A),杜绝 Intel Mac 终端用户的安装失败;
  2. 可选地从 Python 3.13 实验性矩阵中移除 macOS AMD64(选项 C),降低 CI 成本与噪声。

组合方案同时兼顾终端用户体验与 CI 健康度。在 macOS Intel 上损失部分功能被认为是可接受的,因为:Apple 已于 2022 年 6 月停止生产 Intel Mac;PyTorch 已于 2024 年 3 月放弃 Intel Mac 支持;HuggingFace/ML 生态正在快速向 macOS ARM-only 迁移。

四、仓库现状佐证:推荐方案已落地

调查文档提出的是方案;当前仓库源码与 CI 配置则展示了该方案落地后的状态。对照源码可以看到:

1. pyproject.toml 中的平台排除标记已就位

src/backend/base/pyproject.toml 中:

  • altk extra(第 366 行) 已带标记,且注释直接说明了原因——“Excluded on macOS x86_64: PyTorch dropped Intel Mac wheel builds after v2.2.2”:

    altk = ["agent-lifecycle-toolkit>=0.10.1,<1.0; sys_platform != 'darwin' or platform_machine != 'x86_64'"]
    
  • langchain-huggingface extra(第 373 行) 同样带标记,注释写明“transitive torch dependency (via sentence-transformers) has no Intel Mac wheels”。

  • docling 与 easyocr(第 385–399 行) 保持了同类排除模式,其中 docling 的排除施加在 docling-slim 二进制侧,docling-core 保留。

这与文档“选项 A”的建议完全一致,版本约束虽随时间演进(如 agent-lifecycle-toolkit>=0.10.1,<1.0,注释说明是为 PyTorch 2.6.0 兼容性升级),但平台标记策略未变。

2. CI 矩阵:macOS Intel 被系统性收缩

当前 cross-platform-test.yml 的矩阵体现了“选项 C”精神并已进一步演化:

  • 稳定矩阵中 macOS AMD64 仅保留 Python 3.12 一档,且运行在昂贵的 macos-latest-large 上(矩阵条目);
  • Python 3.13 已从实验性转正为稳定(blocking),但注释明确指出 macOS Intel 被刻意排除,Intel 平台对新 Python 版本的覆盖转移到实验层(矩阵注释);
  • 实验性矩阵当前面向 Python 3.14,macOS Intel 被整体省略,注释 解释得非常透彻:langflow 在 Python 3.14 上要求 onnxruntime>=1.26,而 onnxruntime 自 1.24 起不再发布 macOS x86_64 wheel,因此“macOS Intel + Python 3.14”同样是永久不可满足的组合——保留它只会让昂贵的 macos-latest-large runner 烧在一个“注定失败且无信号”的用例上。

这个注释与本文调查文档形成呼应:同一平台在 PyTorch 与 onnxruntime 两条依赖链上先后触及“Intel Mac wheel 断供”问题,最终都选择了从矩阵中移除而非长期挂红。

3. 当前 lockfile 中 torch 的平台解析

调查文档附录中的 torch 版本表是 2026 年 4 月调查时的快照(2.2.2 / 2.10.0)。当前仓库的 uv.lock 中,torch 已统一解析到更高版本,且依旧按平台分裂为两组来源(均为 https://download.pytorch.org/whl/cpu 索引):

  • 标准版 torch 2.13.0,标记为 macOS arm64 或 Python 3.14+ 的 darwin 环境(见 uv.lock 第 129–130 行);
  • torch 2.13.0+cpu 覆盖非 darwin 或非 arm64 的组合。

从源码结构看,macOS Intel(darwin + x86_64)在新旧两代 lockfile 中都不会被分配到“有 wheel 保证”的条目——平台标记机制持续保证该组合不会走到 torch 的直接依赖路径上,这正是 pyproject 层排除标记在锁定文件中的投影效果。

五、附录:受影响的 Lockfile 条目(调查时点快照)

调查文档附录记录了当时 uv 按平台解析出的 torch / torchvision 版本矩阵,完整保留如下。

torch 按平台解析的版本

版本 平台 Python 有 wheel?
2.2.2 macOS x86_64 < 3.13 是(cp310、cp311、cp312)
2.2.2+cpu macOS x86_64 >= 3.13
2.10.0 macOS arm64 全部 是(cp310–cp313)
2.10.0+cpu Linux/Windows 全部 是(cp310–cp313)

torchvision 按平台解析的版本

版本 平台 Python 有 wheel?
0.17.2 macOS x86_64 < 3.13 是(cp310、cp311、cp312)
0.17.2+cpu macOS x86_64 >= 3.13
0.25.0 macOS arm64 全部
0.25.0+cpu Linux/Windows 全部

六、可复用的方法论总结

这篇调查文档及其在仓库中的落地,沉淀出一套处理“上游二进制支持断供”问题的通用方法,值得在类似项目中复用:

  1. 先定性再动手:用 lockfile 反查“解析选中了哪个版本、该版本在目标平台是否有 wheel”,把“依赖冲突”与“二进制缺失”区分开。本案例中 uv 解析本身成功,失败在安装阶段,根因在上游平台支持矩阵而非本项目依赖声明的错误。
  2. 用 PEP 508 环境标记做平台级熔断sys_platform != 'darwin' or platform_machine != 'x86_64' 是精确命中单一架构组合的标准写法;对“仅某个 Python 版本 + 某个平台”的坏组合,可叠加 python_version 构成复合标记(选项 B),但需评估跨工具的标记求值兼容性。
  3. CI 分层隔离 EOL 风险:稳定矩阵(blocking)只覆盖有长期支持承诺的“平台 × Python”组合;实验性矩阵用 continue-on-error: true 观察生态演进,并由 summary 任务显式区分“稳定失败=阻断 / 实验失败=可接受”的判定语义(见 汇总任务)。
  4. 在配置文件中留注释讲清“为什么排除”:Langflow 的 pyproject.toml 在每条排除标记前都注明上游版本断供的事实(如 “PyTorch dropped Intel Mac wheel builds after v2.2.2”),使后来者无需重走一遍根因调查。

适用前提与限制:本文结论均基于当前仓库的源码、lockfile 与 CI 配置;PyTorch 上游若改变平台支持策略,或 macOS x86_64 用户群发生变化,选项 A/C 的取舍需要重新评估。对于运行 Langflow 的用户,实操建议是:Intel Mac 用户优先使用 Python 3.12 或以下版本以获得最完整的依赖面,Apple Silicon 用户则不受此问题影响。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384