news 2026/9/18 9:08:04

TorchTitan-NPU 开发者测试审查工作流:UT、NPU ST 与格式审查的完整实践指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TorchTitan-NPU 开发者测试审查工作流:UT、NPU ST 与格式审查的完整实践指南

TorchTitan-NPU 开发者测试审查工作流:UT、NPU ST 与格式审查的完整实践指南

【免费下载链接】torchtitan-npuAscend Extension for torchtitan项目地址: https://gitcode.com/cann/torchtitan-npu

导读

本文以 CANN / torchtitan-npu 仓库内置的开发者测试技能(.agents/skills/developer-tests-review/SKILL.md)为骨架,系统讲解在 PR 开发与审查中如何规范地处理单元测试(UT)、NPU 集成测试(ST)与测试格式问题。你将掌握"更新测试"与"review 测试"两种工作流的完整操作路径、UT 正向功能覆盖的判定标准、NPU ST 路径覆盖的核实方法,以及一套可复用的审查报告输出规范,让每一次测试改动都有清晰的执行依据与可验证的结论。

一、Skill 概述:一套测试治理规则,两种工作模式

在 torchtitan-npu 仓库中,开发者测试的治理被沉淀为一个可复用的 Agent Skill:.agents/skills/developer-tests-review/SKILL.md。它定义了同一套UT、NPU ST 与格式规则,但通过两种工作流施加不同的修改权限与执行权限:

  • Workflow 1:更新测试—— 面向"需要补充、修正或重构 testcase"的场景。允许修改测试代码、测试入口、suite 注册、fixture、golden 或测试配置;除非用户另有授权,不修改生产实现来迁就测试
  • Workflow 2:review 测试—— 面向"静态审查已有 testcase 或 PR 中的测试改动"的场景。只读:不修改测试代码、生产代码、golden 或 skill,也不导入、收集或执行测试,只提交审查报告。

两者的权限差异在 SKILL.md 中被严格区分:更新 workflow 必须"修改 → 执行 → review → 修正"循环迭代直至通过;review workflow 则固定声明"测试执行:未执行(仅静态审查)",绝不把未执行的检查写成通过。

二、共同范围与边界:先读 AGENTS.md,再判断是否适用

两个 workflow 在开始前都必须:

  1. 完整读取仓库的.agents/AGENTS.md,统一用语时读取references/terminology.md,输出前读取references/report-output.md
  2. 明确范围只限本仓库可控的生产代码、测试代码、测试入口和测试资源。

Skill 对第三方依赖变更(如 torchao、torchft)给出了清晰的边界判定:若 PR 仅修改第三方仓库源码/测试、或仅更新依赖版本/提交引用,且未改变本仓库torchtitan_npu/tests/.ci/.gitcode/中的适配调用、注册、配置、入口或资源,则 UT/ST/格式审查结论直接写"不适用"。只有当依赖变更会影响本仓库的适配接口、注册/配置、训练调用路径或测试入口时,才将受影响的本仓路径纳入审查,并把第三方变更记录为"外部前置条件"。

Skill 同时强调一个关键认知:UT 和 ST 不是同一条覆盖链路

  • UT 审查 CPU 上可观察的模块行为、参数传递、路径等价性和独立预期;
  • ST 只审查真实 NPU 集成测试是否进入 PR 改变的训练路径;
  • ST 不读取 CPU UT 的覆盖结论,也不把 CPU UT、CPU oracle 或单元测试计入 ST 覆盖。

三、Workflow 1:更新测试的五步流程

当用户要求补充、修正或重构 testcase 时,进入更新 workflow:

1. 固定范围并读取规则:记录 PR 改变的生产路径、已有测试、测试入口和资源条件。UT 更新读取 references/ut-review.md;ST 更新读取 references/st-review.md,并按其中要求读取目标分支的 tests/integration_tests/README.md 和实际 runner;格式问题读取 references/format-review.md。

2. 设计最小修改:先确认现有测试为什么不能直接提供证据,再修改或新增最小 testcase。UT 必须保护对应正向功能和独立 expected;ST 必须进入实际模型、override、并行和编译组合,并接入现有tests/integration_testsrunner、suite 和结果检查方式。

3. 执行相关检查:UT 修改至少执行修改的 unit test;ST 修改至少通过现有 integration runner 执行修改或新增的 case;涉及 golden 时同时执行对应比较。没有真实 NPU 或其他必需环境时,不得把未执行写成通过

4. 按规则 review 并迭代:检查执行结果和测试代码是否满足相应规则,发现失败、覆盖缺口、无效断言、同源 expected、路径未启用、状态泄漏或格式问题时继续修改并重新执行,直到通过。这一步建议使用 subagent 以减小上下文污染。

5. 输出更新结果:报告修改的文件、每个 testcase 保护的正向功能或 NPU 路径、执行的命令及结果、golden 是否更新,以及仍受环境限制的检查。只有实际执行并通过的检查才能标记为通过。

四、Workflow 2:review 测试的三步流程

review 流程用于静态审查已有 testcase 或 PR 测试改动,全程只读:

1. 固定审查对象:记录基线版本、PR 版本、生产代码路径、PR 测试、已有 UT/ST、测试入口和设备预算。只根据实际生产代码和执行链路判断覆盖,不根据测试名称猜测

2. 选择审查规则:在选择规则前,先从 requirements.txt 和.ci/lint.sh确认固定的 TorchTitan commit。凡是需要拆解前向或训练流程的审查,都必须读取该 commit 对应的上游 torchtitan 源码,沿本仓patchesoverride、模型或算子与上游 trainer、model 和 consumer 的真实调用链核对。上游源码只作为调用链和接口基线;上游仓库的测试不计入本仓 UT/ST 覆盖

3. 输出 review 报告:报告给出已覆盖、部分覆盖、未覆盖、检查无效或不适用的证据,指出准确的测试文件、case 名称、配置组合和最小修改方向。review 不因为发现缺口而直接修改或执行,只提交报告。

两个 workflow 的结论词汇完全统一,只允许四选一:可以合入补充测试后合入暂停并澄清不适用

五、CPU UT Review 规则:从"正向功能"出发的覆盖判定

references/ut-review.md 定义了 CPU 单元测试的更新与 review 规则。核心方法论是先独立写出正向功能:在读取 PR 测试断言之前,从生产代码和用户/训练入口写出"正常输入或配置 → 实际生产路径 → CPU 可观察结果 → expected 来源"。只有不同的用户结果、训练结果或受支持运行方式才拆成不同正向功能;配置、工厂、辅助函数、生产分支和 consumer 通常是同一行中的检查点。

5.1 模块职责类规则(Rules 1)

规则编号审查对象核心要求
1.1配置和 override测试必须从真实配置、registry 或override.imports入口进入目标实现;只导入模块或手动构造对象不能证明真实配置选择了该实现
1.2模型和共享组件模型测试必须从真实 registry/config 进入被修改的主要前向路径;共享组件测试必须使用其实际调用者提供的输入表示
1.3算子 wrapper 和 autograd必须检查 wrapper 的生产参数、输入输出 shape/dtype、CPU 可观察输出和受影响的梯度;若 PR 改变 backward 或 saved activation,必须直接比较相关输入、score、metadata 或参数梯度
1.4patch 和替换必须从真实导入或 apply 入口确认目标上游符号已被替换,并确认实际使用位置收到替换后的对象;只断言 patch 函数被调用不能证明替换后的行为
1.5metadata、数据和并行必须确认生产者生成的对象被实际 consumer 接收,并检查 shape、dtype、boundary、route row 或 placement;CPU 测试不能把真实 NPU/HCCL 结果当作已验证
1.6compile必须从真实入口确认目标 backend、选项或图替换实际生效,并断言编译后仍得到声明的 CPU 结果;只检查配置字段存在不算覆盖
1.7checkpoint 和状态映射必须断言具体 key、tensor、dtype、placement 或恢复后的状态,不能只比较 key 数量、文件存在或保存函数返回成功
1.8固定上游版本从 PR 版本的依赖文件和 CI 脚本确认实际固定的 TorchTitan 版本,报告写明上游符号、测试路径和版本
1.9多种实现的精确选择同一目标存在 golden/cann/workaround 等实现时,确认一条override.imports只启用请求的工厂,不隐式启用同模块其他实现
1.10自动生效的兼容 patch修改torchtitan_npu/patches/下随包导入生效的 patch 时,从本仓包导入或 apply 入口确认替换已安装,再检查该 patch 负责的最小行为
1.11共享实现和新模型修改共享 attention、normalization、RoPE、MoE 或 decoder 时,先保护共享实现的输出、形状和类型;新增模型时至少一条 CPU UT 必须使用真实注册配置构建小模型并进入主要前向路径

5.2 正向入口与路径等价性(Rules 2–4)

正向入口规则强调:正向测试应从用户实际使用的入口开始,至少走到 CPU 能观察的承诺结果;必须检查目标确实启用(配置、注册、替换实现、补丁、编译或回退路径可能静默绕过新代码);断言只覆盖能区分正确行为与错误行为所需的输出、形状、类型、参数、状态、放置或持久化值。

路径等价性规则(Rules 4)适用于 score、scale、mask、clamp、activation、dtype、quantization、bias、route row、permute/unpermute、collective、saved activation 或 backward 路径发生变化,或 PR 声称"数学等价""只优化性能"的场景。其要点包括:

  • 测试设计必须先写出旧路径、新路径、两者应相等的条件以及有意变化的预期,不要把"都能运行"或"训练 loss 相近"当作路径等价条件
  • 旧路径和新路径必须分别与独立 dense/reference expected 比较,可接受来源包括手算小例子、独立 PyTorch 实现、固定且注明版本的上游实现、数学性质和保存/加载往返;不能复制待测算法生成 expected,也不能直接录制待审代码输出作为 golden
  • 等价测试必须比较受影响的 forward 输出、输入梯度、score 或 metadata 梯度以及参数梯度,只比较最终 loss 不足以保护改变了 backward 或 saved activation 的 PR;
  • 涉及 AllToAll 的 CPU 契约必须使用真实 2-rank Gloo collective 检查 rank 间的排列、聚合和返回结果,fake permutation 只能证明局部排列逻辑。

Skill 甚至对 router-score 的具体契约给出了可执行的判据(Rule 4.8-4.10):对无 bias 的 dense expert,若生产路径把 score 从hidden @ W2.T之后移动到之前,测试必须明确比较post = (hidden @ W2.T) * scorepre = (hidden * score) @ W2.T的独立结果,并使用固定 float64 输入、交错 expert ids、非均匀 scores/counts 构造 fixture,让 input、scores 和权重参与固定 scalar loss 或 upstream gradient。

5.3 expected 质量、Fake 边界与状态隔离(Rules 5–9)

  • expected 来源必须来自手算、独立实现、固定上游、数学性质或保存/加载往返;预期值不能由待测路径、同一 helper 或同一生产对象生成。
  • 断言区分能力:断言必须能够让一个具体错误实现失败。只断言不抛异常、有限值、对象非空、调用次数或 key 数量,不能支持名称中声称的数值、路由、替换或恢复结果。
  • Fake/Stub/Spy 边界:可以隔离 NPU、进程、外部服务或昂贵操作,但不能替代正在声明验证的计算、目标选择、参数传递或张量放置;CPU fake、模拟进程组或模拟 NPU 算子不能证明真实 NPU kernel、HCCL、跨 rank 梯度或完整训练结果。
  • 状态隔离:测试必须恢复其修改的 RNG、环境变量、registry、monkeypatch、process group、临时文件、单例、钩子和 import cache;随机输入使用局部 generator 或可恢复的 RNG 范围;测试不得依赖另一条测试先执行,也不得依赖未声明的网络、设备或外部初始化。

5.4 低价值 UT 判定原则(Rules 10)

这是本仓库对"哪些 UT 不值得长期保留"的独立方法论,也可参见 low-value-ut-principles.md:

  • 先判断删除后失去什么:如果删除后仍有另一条测试保护相同的用户可观察行为、受支持边界或数值语义,这条测试通常是重复的;
  • 私有不等于低价值:私有函数如果实现了数值变换或状态映射,仍可能是高价值测试对象;
  • 防御性校验只保留不可替代的约束:不应为每个 dtype、shape、device 和错误组合建立长期拒绝矩阵;
  • 配置测试不要复写 Python 实现:不应把partial类型、函数名、keywords字典、内部 tuple、对象 identity 或当前常量排列当成稳定契约;
  • 性能机制不能用字段存在代替结果:host cache、减少.item()同步、缓存 metadata 等属于实现机制,只断言seq_len_hostn_cmp_blocks_host等字段存在通常是低价值 implementation test;
  • 退化数据会制造低价值测试:全零、完全对称或线性参数使不同公式得到相同结果的 fixture,测试只是在重复实现。

六、NPU ST Review:只回答一个问题的覆盖核实

references/st-review.md 开宗明义:ST 审查只回答一个问题——现有tests/integration_tests是否覆盖了 PR 改变的真实 NPU 训练路径。ST 不读取 CPU UT 的覆盖结论,也不把 CPU UT、CPU oracle 或单元测试计入 ST 覆盖。

6.1 四条核心规则

  1. Testcase 来源:ST testcase 只能来自tests/integration_tests的注册和执行链路。默认从.ci/smoke_test.sh追踪到tests.integration_tests.run_tests,再追踪到build_*_test_list和具体OverrideDefinitions;被disabled、suite 未注册或入口不会选择的 case 不算覆盖。
  2. 覆盖判定:一个 case 只有在真实命令中使用了目标模型和配置、目标override.imports或融合实现、目标并行数值、目标编译选项,并进入真实训练入口时,才覆盖对应路径。仅在 README、case 名称或配置字符串中声明目标条件,不算覆盖
  3. 完成证据:每个被计入的 case 都必须有可观察的训练完成条件(指定训练步正常退出、初始化、前向、反向和优化器步骤完成)。check_loss=True的 case 还要读取对应 golden 并比较 loss;check_loss=False的 case 只能做完成性检查,报告必须记录原因,不能把它写成数值等价证明
  4. 复用优先 / 最小组合:现有 case 能进入目标路径则优先复用;只缺新增条件就调整;确实无法进入才新增。新增 case 必须使用现有run_tests.pyOverrideDefinitions、suite 注册、启动脚本和结果检查方式,不得通过修改.ci/smoke_test.sh来绕过模型列表或建立专用入口。新增或调整的 case 只保留能触发 PR 改动的最小模型、并行和编译组合,单个 PR 阶段不超过 4 张 NPU。

6.2 仓库中的 ST 基础设施验证

从源码看,这套规则与本仓库的集成测试设施完全对应:

  • tests/integration_tests/run_tests.pybuild_models_test_list()聚合build_deepseek_v4_test_list()build_deepseek_v41_test_list()build_deepseek_v3_2_test_list(),构成默认 smoke suite;
  • tests/integration_tests/__init__.py中的OverrideDefinitions定义了override_argstest_namengpudisableduse_goldencheck_lossexpected_stepscheck_resumeverify_ema_checkpoint等字段;
  • tests/integration_tests/README.md 记录了完整测试矩阵,其中use_goldencheck_loss是两个独立维度use_golden仅决定使用 Golden 参考算子还是 SMLA/NPU override;check_loss决定是否启用 deterministic、读取参考 loss 并执行精确数值比较。

以 DeepSeek-V4 的 case 为例(可对照tests/integration_tests/deepseek_v4.py):dsv4_golden_1rankdsv4_golden_ep2_fsdp2设置check_loss=True做精确 loss 比较;dsv4_smla_1rank_aot_eagerdsv4_smla_ep2_fsdp2dsv4_smla_cp2_ep2_fsdp2dsv4_mtp_smla_cp2_headtail四个 SMLA case 设置check_loss=False(SMLA 暂不支持--debug.deterministic),用于覆盖 SMLA/NPU override 在单卡、EP+FSDP、CP+EP+FSDP 以及 MTP+CP 场景下的实际构图、编译和训练执行路径。Golden loss 锚定文件位于tests/assets/losses/(如dsv4_golden_1rank.txtdsv4_golden_ep2_fsdp2.txtdsv41_golden_2p_ep2_fsdp2.txt)。

七、格式审查:组织、收集、命名与隔离的独立维度

references/format-review.md 只审查测试文件的组织、收集、命名、可读性和隔离,不判断生产功能是否覆盖,也不判断 CPU 数值或真实 NPU 训练是否正确

格式审查有明确的依据优先级:PR 版本中的pyproject.toml、pre-commit、测试入口和.agents规则 → 被修改的同一测试文件 → 同一生产模块的相邻测试 → 当前固定 TorchTitan 版本中的同模块测试 → pytest 和 Python 的公开约定。发生冲突时使用更靠前且更具体的依据。

关键规则摘要:

  • 文件位置:CPU UT 以tests/unit_tests为根目录,与生产代码目录一一对应(torchtitan_npu/<area>/<module>tests/unit_tests/<area>/<module>/test_*.py);NPU 集成 testcase 必须由对应build_*_test_list注册;golden 放在tests/assets或 integration 约定目录,文件名必须能稳定映射到 testcase;
  • pytest 收集:pytest 测试类不定义__init__;参数化测试不能依赖case0、对象地址或长元组作为唯一名称,需要提供简短稳定的ids=
  • 命名:顶层函数优先使用test_<对象或动作>_<条件或预期结果>;避免单独使用basicnormalsuccesscase1unaffectedregression等离开正文无法定位的词;名称声称端到端、真实 tokenizer、真实 NPU、loss golden 时,测试代码必须处于相应层级并包含对应检查;
  • 结构:导入默认置顶,准备、真实调用和断言之间用空行分开;断言应靠近产生被测结果的调用;不能把关键断言藏在一个名为run_casecheck_all的泛化 helper 中;
  • 隔离:RNG、环境变量、debug 开关、registry、monkeypatch、单例、钩子、process group、sys.modules和 import cache 的修改必须可靠恢复;临时文件使用测试独占目录。

格式审查结论有严格的边界:格式问题只描述文件、收集、命名、结构、可读性和隔离事实,不能直接判定正向功能未覆盖、ST 缺失、数值错误或生产代码错误——这些结论必须转到 ut-review 或 st-review。

八、审查报告输出规范与术语统一

references/report-output.md 定义了审查报告的格式约束:

  • Markdown 是唯一正文来源,聊天只给结论、合入前置条件和文件链接;需要 HTML/PDF 时运行scripts/render_review_report.py <report.md> <report.html>,再用 WeasyPrint 生成 PDF;
  • 合入建议四选一可以合入补充测试后合入暂停并澄清不适用review测试报告固定写明"测试执行:未执行(仅静态审查)";更新测试报告必须列出实际执行的命令、结果和环境;
  • 报告顺序:结论、语义变换与独立 oracle 表、UT 正向功能覆盖表和 ST 触发判断必须放在报告前部,紧跟结论;随后是生产代码变更、受影响模块和使用位置、合入前置条件与格式问题、4 张 NPU ST 事实表、ST 不能证明的内容、附录;
  • 核心表格包括 UT 覆盖表(正向功能 / 生产代码和应观察结果 / PR 中的直接检查 / 状态 / 合入前置条件)、ST 触发判断表(生产代码变更 / 受影响训练场景 / 为什么需要 ST / 现有代表测试 / 判断 / 合入前置条件)、格式表和 4 张 NPU ST 事实表;
  • 用语规范:写"override.imports选择了哪个工厂并替换了哪个配置",不写"约定"或"连接";写"测试入口静态包含该文件",不写"测试已通过";写"有限损失只能发现严重失败",不写"数值正确";写"需要 NPU 算子前向/反向与独立实现对照",不把它算作 ST 已证明的内容。

references/terminology.md 提供了统一术语对照,例如:happy path → 正向功能/正常支持路径;handoff/contract → 参数传递/接口约束;evidence → 直接检查/测试依据;carrier → 现有代表测试;activation → 启用检查;No-ST → 无需系统测试覆盖。

仓库还提供了可直接套用的 report-template.md,它包含版本信息区、结论区(含阻塞问题与合入前置条件的约 20 行伪代码区)、语义变换与独立 oracle 表、UT 正向功能覆盖表、ST 触发判断表、4 张 NPU ST 事实表及按模型投影,以及附录区。模板要求"部分覆盖"行必须使用警示色高亮,且"语义变换存在但独立 oracle 未闭合时,合入建议只能是补充测试后合入"。

九、典型场景演练:一个 PR 的完整测试治理路径

结合以上全部规则,一个 PR 从提交到合入的测试治理路径如下:

  1. 读规则:读取.agents/AGENTS.md,判定 PR 改动是否落入本仓测试治理范围;若只改第三方依赖且不影响本仓适配路径,结论为"不适用";
  2. 区分 UT 与 ST:对torchtitan_npu/下的生产改动,先沿真实入口(registry、override.imports、patches apply)写出 CPU 可观察的正向功能;再对照tests/integration_testsbuild_*_test_listOverrideDefinitions判断真实 NPU 训练路径是否被现有 case 覆盖;
  3. 执行格式审查:按 format-review.md 的优先级核对文件位置、收集、命名、结构和隔离,格式问题单独成表;
  4. 决定工作流:review 模式只读并输出报告;更新模式则"修改 → 执行 → review → 修正"循环,UT 至少执行修改的 unit test,ST 至少通过现有 integration runner 执行修改或新增的 case;
  5. 输出报告:按 report-template.md 生成 Markdown,给出四选一结论与精确的合入前置条件(准确测试路径、稳定测试名称、最小准备、真实调用、具体断言和 expected 来源)。

十、配套资源索引

Skill 及其配套文件集中在.agents/skills/developer-tests-review/目录下,与其协作的仓库资源包括:

用途路径
Skill 主文件(两种 workflow 定义).agents/skills/developer-tests-review/SKILL.md
CPU UT 更新与 review 规则.agents/skills/developer-tests-review/references/ut-review.md
NPU ST review 规则.agents/skills/developer-tests-review/references/st-review.md
格式审查规则.agents/skills/developer-tests-review/references/format-review.md
报告输出规范与术语表.agents/skills/developer-tests-review/references/report-output.md、terminology.md
报告模板与渲染脚本.agents/skills/developer-tests-review/assets/report-template.md、render_review_report.py
集成测试基础设施说明tests/integration_tests/README.md
integration runner 与 case 定义run_tests.py、deepseek_v4.py、deepseek_v41.py、deepseek_v3_2.py
CI 入口脚本.ci/smoke_test.sh、.ci/unit_test.sh
golden loss 资产tests/assets/losses
低价值 UT 原则(独立文档版)low-value-ut-principles.md
单元测试架构说明unit-test-architecture.md

结语

torchtitan-npu 将测试治理沉淀为 Skill 而非零散文档,其核心价值在于三点:一是权限分明(更新与 review 两种工作流共用规则但权限不同);二是证据链严格(UT 要求独立 expected 与真实入口、ST 要求真实 NPU 路径与完成证据、格式要求静态可读事实,三者互不替代);三是输出可执行(四选一结论、带警示色的覆盖表、精确到文件与 case 名称的合入前置条件)。这套方法论不仅适用于本仓库的 DeepSeek-V4 / V4.1 / V3.2 模型测试治理,也为大型开源项目的 PR 测试质量把关提供了一个可复制的工程范式。

【免费下载链接】torchtitan-npuAscend Extension for torchtitan项目地址: https://gitcode.com/cann/torchtitan-npu

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 9:05:26

嵌入式工控机选型:五大工业指标与采购验收指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 9:02:58

mysql-for-visualstudio安装与实战:打通Visual Studio与MySQL连接

做 .NET 开发的人&#xff0c;尤其是项目里数据库选了 MySQL 的&#xff0c;大概率都撞过这种尴尬&#xff1a;Visual Studio 里默认数据源只有 SQL Server&#xff0c;想直接连个 MySQL 表看看数据&#xff0c;右键“添加连接”翻遍列表也找不到 MySQL 的影子。这时你会意识到…

作者头像 李华
网站建设 2026/9/18 9:02:30

接口压力测试实战:从工具选型到容量规划与瓶颈定位

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 9:02:07

将 24.4pp 差距压到 12.0pp,TaoToken 改 GPT-4.1 智能体 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/18 8:53:24

Anker黑客松备战指南:从报名到Demo演示的完整攻略

1. 一家把充电做透的公司办黑客松&#xff0c;背后在想什么1.1 先看懂 Anker 的“硬件软件”版图9 月 7 日&#xff0c;Anker 首届黑客松挑战赛报名启动。消息出来当天&#xff0c;我身边不少做开发的朋友第一反应都是&#xff1a;一家靠充电器、充电宝、储能电源出圈的消费电子…

作者头像 李华