<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>ZZHow Blog</title>
        <link>http://blog.zzhow.com/</link>
        <description>ZZHow 博客</description>
        <lastBuildDate>Wed, 12 Aug 2026 16:38:16 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2026, ZZHow</copyright>
        <item>
            <title><![CDATA[Ascend C算子开发（进阶）笔记]]></title>
            <link>http://blog.zzhow.com/article/AscendC-Intermediate</link>
            <guid>http://blog.zzhow.com/article/AscendC-Intermediate</guid>
            <pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Ascend C算子开发（进阶）笔记，包含 AI Core 架构抽象；Ascend C 编程对象；Vector 算子开发流程；Add 算子实现与运行验证；Host 侧实现；Tiling 下发；固定 Shape 与动态 Shape 的 Tiling；Shape 推导；算子原型注册；算子开发工程；Kernel 直调工程；自定义算子工程；算子工程编译与部署；Ascend C 基础 API 与高阶 API；Tensor 高维切分参数；数据搬运、内存管理与任务同步；算子的多种调用方式；Kernel 直调；Ascend CL 调用算子；PyTorch 调用算子；非对齐数据处理；尾块处理；复杂 Tiling 实现；多数据类型算子实现]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-3b8e64bde40f8091a627e744b395fd78"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-sync-block notion-block-3bae64bde40f80e6ba8ddc3aa27df06a"><div class="notion-text notion-block-3b8e64bde40f809389d7f7f284b2a8c0">@ZZHow(ZZHow1024)</div><div class="notion-text notion-block-3b8e64bde40f807c8412f076488f55db">参考课程：</div><div class="notion-text notion-block-3b8e64bde40f80bf9ea1f9584cf68d9d"><b>【Ascend C算子开发（进阶）】</b></div><div class="notion-text notion-block-3b8e64bde40f8006a814d63e1d0b3a51"><b>[</b><b><a class="notion-link" href="https://www.hiascend.com/developer/courses/detail/1696414606799486977" target="_blank" rel="noopener noreferrer">https://www.hiascend.com/developer/courses/detail/1696414606799486977</a></b><b>]</b></div><div class="notion-text notion-block-3b8e64bde40f80bfb583c0485f694fb7"><b>【Ascend C系列教程（中级）】</b></div><div class="notion-text notion-block-3b8e64bde40f800092d4d211d3cbbe66"><b>[</b><b><a class="notion-link" href="https://www.bilibili.com/video/BV16T421r7cX" target="_blank" rel="noopener noreferrer">https://www.bilibili.com/video/BV16T421r7cX</a></b><b>]</b></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3bae64bde40f8018b1c0d49913c09974" data-id="3bae64bde40f8018b1c0d49913c09974"><span><div id="3bae64bde40f8018b1c0d49913c09974" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8018b1c0d49913c09974" title="1-一个Add算子的前世今生"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1-一个Add算子的前世今生</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80af99d7d239950257db" data-id="3bae64bde40f80af99d7d239950257db"><span><div id="3bae64bde40f80af99d7d239950257db" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80af99d7d239950257db" title="1-1 AI Core 架构抽象回顾"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1-1 AI Core 架构抽象回顾</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80bb8face38fa825e4ff" data-id="3bae64bde40f80bb8face38fa825e4ff"><span><div id="3bae64bde40f80bb8face38fa825e4ff" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80bb8face38fa825e4ff" title="AI Core 的逻辑组成"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">AI Core 的逻辑组成</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d1b2b6f4ae467c694f"><li><span class="notion-red"><b>AI Core</b></span> 是昇腾 AI 处理器中的<span class="notion-red"><b>主要计算核心</b></span>。进行 Ascend C 算子开发时，可以把 AI Core 抽象为三类核心资源：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d1b2b6f4ae467c694f"><li><span class="notion-red"><b>计算单元</b></span>：负责实际运算。</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d39befdf60a707881c"><li>Scalar：标量计算与控制相关处理。</li><li>Vector：向量计算，适合逐元素、向量类操作。</li><li>Cube：矩阵/块矩阵类计算。</li></ul><li><span class="notion-red"><b>存储单元</b></span>：包括片上 Local Memory，用于保存当前 AI Core 正在处理的数据。</li><li><span class="notion-red"><b>搬运单元</b></span>：在 Global Memory 与 Local Memory，以及不同逻辑存储位置之间搬运数据。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80139831ce6bc1ca2eeb"><li>AI Core 的向量计算采用 SIMD 思想：一条指令可以并行处理一组数据，因此算子实现时需要特别关注数据块大小、对齐方式、并行切分和流水调度。</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3bae64bde40f8050bedfec21a19ba453"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3Aa3b31717-4a26-4b0f-ad24-efe089f43afc%3AAI_Core_%E9%80%BB%E8%BE%91%E6%9E%B6%E6%9E%84%E6%8A%BD%E8%B1%A1.png?table=block&amp;id=3bae64bd-e40f-8050-bedf-ec21a19ba453&amp;t=3bae64bd-e40f-8050-bedf-ec21a19ba453" alt="AI Core 逻辑架构抽象" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">AI Core 逻辑架构抽象</figcaption></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8015a079d25c60cbba6f" data-id="3bae64bde40f8015a079d25c60cbba6f"><span><div id="3bae64bde40f8015a079d25c60cbba6f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8015a079d25c60cbba6f" title="外部存储与内部存储"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">外部存储与内部存储</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80c9996cd6715b5a511e"><li>Ascend C 中常用<span class="notion-red"><b>两类 Tensor 对象</b></span>来表达数据所在的位置：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80c9996cd6715b5a511e"><table class="notion-simple-table notion-block-3bae64bde40f801bae95ff07d38f581f"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f80d0887de0395961af1c"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">对象</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">所在位置</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">作用</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80d3b3a6fecc2e456ce2"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell"><code class="notion-inline-code">GlobalTensor</code></div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">Global Memory</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">表示外部存储中的全局数据，通常与核函数传入的 GM 地址关联</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80d09c38d95b6d368095"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell"><code class="notion-inline-code">LocalTensor</code></div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">Local Memory</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">表示 AI Core 片上内存中的局部数据，供计算 API 直接使用</div></td></tr></tbody></table></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f805e94e4cd67459fd139"><li>典型处理流程是：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f805e94e4cd67459fd139"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f807586e0f4384eb49b16"><li>因此，很多 Ascend C 算子的核心都可以归纳成<span class="notion-red"><b>三个阶段</b></span>：<span class="notion-red"><b>CopyIn → Compute → CopyOut</b></span>。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f807d804cde86d5d44d8d" data-id="3bae64bde40f807d804cde86d5d44d8d"><span><div id="3bae64bde40f807d804cde86d5d44d8d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f807d804cde86d5d44d8d" title="GlobalTensor"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">GlobalTensor</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f800aa09ad7ac977bc630"><li><code class="notion-inline-code">GlobalTensor</code> 用于描述 Global Memory 上的数据。通常先用核函数参数获得全局内存地址，再把该地址绑定到 <code class="notion-inline-code">GlobalTensor</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f807e8297c683021dbbfd"><li>概念上可以理解为：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f807e8297c683021dbbfd"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f808497e0db9188c23fb4"><li>之后可以通过下标或切片方式确定当前核需要处理的全局数据范围。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f809e8773dcdd18e58295" data-id="3bae64bde40f809e8773dcdd18e58295"><span><div id="3bae64bde40f809e8773dcdd18e58295" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f809e8773dcdd18e58295" title="LocalTensor"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">LocalTensor</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80bf9826d2a26b6f4bd9"><li><code class="notion-inline-code">LocalTensor</code> 用于描述 Local Memory 上的数据。Vector 等计算 API 的输入、输出通常是 <code class="notion-inline-code">LocalTensor</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f803fb772eef8ac90aab7"><li>LocalTensor 可以进行偏移访问，例如从一个较大的局部 Tensor 中取得某一段数据。算子内部通常不会手工管理裸地址，而是通过 <code class="notion-inline-code">TPipe</code>、<code class="notion-inline-code">TQue</code> 和 <code class="notion-inline-code">LocalTensor</code> 完成片上内存的申请、复用和释放。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8091a1a4e759becbd359" data-id="3bae64bde40f8091a1a4e759becbd359"><span><div id="3bae64bde40f8091a1a4e759becbd359" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8091a1a4e759becbd359" title="逻辑位置 QuePosition"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">逻辑位置 QuePosition</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80afbaade344da4d0573"><li>Ascend C 使用逻辑存储位置表达不同流水阶段中的数据位置。不同逻辑位置对应不同的硬件访问通路，开发者主要<span class="notion-red"><b>通过 Queue 管理它们之间的数据流转</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80838130c2ba08115409"><li>常见位置包括：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80838130c2ba08115409"><table class="notion-simple-table notion-block-3bae64bde40f800aa2f7c938b1f95871"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f80ddb5c0febc31c3dccf"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">QuePosition</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">典型用途</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f807fa5e6c403addc3a25"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">VECIN</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">Vector 计算输入</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80828f99c6377eff1b28"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">VECCALC</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">Vector 中间计算数据</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80778651d16cde9f880e"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">VECOUT</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">Vector 计算输出</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8078b042f82140421c91"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">A1</code>、<code class="notion-inline-code">A2</code>、<code class="notion-inline-code">B1</code>、<code class="notion-inline-code">B2</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">Cube / 矩阵计算相关输入与中间位置</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80509e03d629a7a01f89"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">CO1</code>、<code class="notion-inline-code">CO2</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">Cube / 矩阵计算相关输出位置</div></td></tr></tbody></table></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f801199eee3c466d34d36"><li>使用这些逻辑位置时，不需要直接理解底层物理存储结构，但需要明确：<span class="notion-red"><b>数据处于哪个流水阶段、后续由哪个计算单元消费</b></span>。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f8033aeaceadfad6eda71" data-id="3bae64bde40f8033aeaceadfad6eda71"><span><div id="3bae64bde40f8033aeaceadfad6eda71" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8033aeaceadfad6eda71" title="1-2 Ascend C 的编程对象"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1-2 Ascend C 的编程对象</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80fe8387ee5f41b62c60" data-id="3bae64bde40f80fe8387ee5f41b62c60"><span><div id="3bae64bde40f80fe8387ee5f41b62c60" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80fe8387ee5f41b62c60" title="AI Core 内部并行计算的抽象"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">AI Core 内部并行计算的抽象</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80258eeae7138669f69d"><li>Ascend C 算子最终运行在 AI Core 上。一个 AI 处理器中存在多个 AI Core，<span class="notion-red"><b>多核之间</b></span>通过 <span class="notion-red"><b>SPMD 模型</b></span>并行执行同一份核函数代码，只是不同核处理的数据区间不同。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f804abac6d8743855b0d2"><li>单个 AI Core 内又包含计算、存储和搬运资源，因此 Ascend C 编程同时需要处理两层并行：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f804abac6d8743855b0d2"><li><span class="notion-red"><b>核间并行</b></span>：多个 AI Core 分担不同数据。</li><li><span class="notion-red"><b>核内并行</b></span>：数据搬入、计算、搬出尽可能通过流水重叠执行。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80e38869e8d8d35a22b3" data-id="3bae64bde40f80e38869e8d8d35a22b3"><span><div id="3bae64bde40f80e38869e8d8d35a22b3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80e38869e8d8d35a22b3" title="SPMD 模型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">SPMD 模型</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80daa653c24bead061cd"><li>Ascend C 采用 <span class="notion-red"><b>SPMD（Single Program Multiple Data）</b></span>编程模型：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80daa653c24bead061cd"><li><span class="notion-red"><b>多个 AI Core 执行同一份核函数代码</b></span>。</li><li>每个核通过不同的 <code class="notion-inline-code">block_idx</code> 区分自己的任务。</li><li>核函数中可通过 <code class="notion-inline-code">GetBlockIdx()</code> 获取当前核的逻辑 ID。</li><li>Host/Tiling 决定使用多少个核以及每个核处理多少数据。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80159ac7fcca61206bf8"><li>可以把不同 AI Core 理解为<span class="notion-red"><b>执行同一个程序的多个“工作实例”</b></span>：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80159ac7fcca61206bf8"></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f802481befcb0d2437def" data-id="3bae64bde40f802481befcb0d2437def"><span><div id="3bae64bde40f802481befcb0d2437def" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f802481befcb0d2437def" title="Pipe 与 Queue"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Pipe 与 Queue</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8059a851cdb81027ecad"><li>在核内，Ascend C 把数据处理流程拆成<span class="notion-red"><b>多个流水任务（Stage）</b></span>，使用：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8059a851cdb81027ecad"><li><code class="notion-inline-code">TPipe</code>：管理任务间使用的片上内存。</li><li><code class="notion-inline-code">TQue</code>：负责不同 Stage 之间的数据传递和同步。</li><li><code class="notion-inline-code">AllocTensor()</code> / <code class="notion-inline-code">FreeTensor()</code>：从 Queue 对应的缓冲区申请、释放 <code class="notion-inline-code">LocalTensor</code>。</li><li><code class="notion-inline-code">EnQue()</code> / <code class="notion-inline-code">DeQue()</code>：将 Tensor 放入/取出 Queue。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80269336f0184737564b"><li>这套机制的重点不是“保存一个容器”，而是建立 <span class="notion-red"><b>数据依赖 + 内存复用 + 流水同步</b></span>。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80938245ce192f2d7d79" data-id="3bae64bde40f80938245ce192f2d7d79"><span><div id="3bae64bde40f80938245ce192f2d7d79" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80938245ce192f2d7d79" title="1-3 Vector 算子开发流程——以 Add 为例"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1-3 Vector 算子开发流程——以 Add 为例</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80719d48c85c9166be79" data-id="3bae64bde40f80719d48c85c9166be79"><span><div id="3bae64bde40f80719d48c85c9166be79" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80719d48c85c9166be79" title="算子分析"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">算子分析</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f803ba060ded80d009f37"><li>Add 是典型的逐元素 Vector 算子：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8020a1d4d90940f1af7b"><li>示例约定：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8020a1d4d90940f1af7b"><table class="notion-simple-table notion-block-3bae64bde40f808d9fa8cf00c5cb1894"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f8059b16fe6ae35dae0e5"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">项目</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">内容</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80ceb644e95c5f8867ba"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">输入</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">x</code>、<code class="notion-inline-code">y</code></div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80bbbdf7c2b729fc79a4"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">输出</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">z</code></div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80478067d46a03e1a83a"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">Shape</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">(8, 2048)</code></div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80868c02dd660a050182"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">数据类型</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">half</code></div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80ebbfa0ccdd38c133ec"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">Format</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">ND</code></div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80b89a07e1a802d9d964"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">核函数名称</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">add_custom</code></div></td></tr></tbody></table></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80ff833adfbcbc4bb3af"><li>实现时需要明确三类接口：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80ff833adfbcbc4bb3af"><li>数据搬入：使用 <code class="notion-inline-code">DataCopy</code> 等接口将输入从 Global Memory 搬入 Local Memory。</li><li>计算：使用 <code class="notion-inline-code">Add</code> 等 Vector API 完成逐元素加法。</li><li>数据搬出：将计算结果从 Local Memory 搬回 Global Memory。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80769f9ae92b9b12c78f" data-id="3bae64bde40f80769f9ae92b9b12c78f"><span><div id="3bae64bde40f80769f9ae92b9b12c78f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80769f9ae92b9b12c78f" title="开发流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">开发流程</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b39fc8ef0c09fa362d"><li>Vector 算子开发可概括为：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b39fc8ef0c09fa362d"></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f806fb71eecbc366b4d88" data-id="3bae64bde40f806fb71eecbc366b4d88"><span><div id="3bae64bde40f806fb71eecbc366b4d88" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f806fb71eecbc366b4d88" title="核函数定义"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">核函数定义</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80939cd8d3468e9df290"><li>Ascend C 核函数使用 <code class="notion-inline-code">__global__</code> 和 <code class="notion-inline-code">__aicore__</code> 等限定符，设备侧代码直接在 AI Core 上执行。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80468005c91b54f12e29"><li>典型形式：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80468005c91b54f12e29"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80889899cd8a60f47277"><li>核函数入口本身通常保持简洁：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80889899cd8a60f47277"><li>创建算子实现类。</li><li>调用 <code class="notion-inline-code">Init()</code> 完成地址绑定、切分参数计算和 Queue 初始化。</li><li>调用 <code class="notion-inline-code">Process()</code> 执行流水。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80f4b134e114be67f0c5" data-id="3bae64bde40f80f4b134e114be67f0c5"><span><div id="3bae64bde40f80f4b134e114be67f0c5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80f4b134e114be67f0c5" title="流水任务设计"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">流水任务设计</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a092b2fb70efd9c40d"><li>Vector 算子通常把一次完整处理拆为<span class="notion-red"><b>三个 Stage</b></span>：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a092b2fb70efd9c40d"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f803c9a28ee45fc6b4af2" style="list-style-type:decimal"><li><span class="notion-red"><b>CopyIn</b></span>：Global Memory → Local Memory。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f80d98d4feaa635b08e27" style="list-style-type:decimal"><li><span class="notion-red"><b>Compute</b></span>：Local Memory 中完成 Vector 计算。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f80aca444f9fe20304f69" style="list-style-type:decimal"><li><span class="notion-red"><b>CopyOut</b></span>：Local Memory → Global Memory。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80688bcafd7761b0a7db"><li>当一份输入被切成多个 Progress 后，<span class="notion-red"><b>不同 Progress 可以处于不同 Stage</b></span>，从而形成流水并行。例如：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80688bcafd7761b0a7db"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f808fa7a6cef945878700"><li>这使搬运单元和计算单元不必长期互相等待。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80eeaf34fe1ac663de48" data-id="3bae64bde40f80eeaf34fe1ac663de48"><span><div id="3bae64bde40f80eeaf34fe1ac663de48" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80eeaf34fe1ac663de48" title="算子类的典型结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">算子类的典型结构</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b596e6d8f54e2c7c4b"><li>这套结构的意义是把<span class="notion-red"><b>内存初始化、任务调度和三个流水阶段分离</b></span>，后续修改切分策略或计算逻辑时更容易维护。</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3bae64bde40f807ebf46d67c3bafc08b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3Ad0e12b26-7fbd-4e2d-bc80-fc899fb910e4%3AVector_%E7%AE%97%E5%AD%90%E6%B5%81%E6%B0%B4%E4%BB%BB%E5%8A%A1%E4%B8%8E%E6%95%B0%E6%8D%AE%E9%80%9A%E8%B7%AF.png?table=block&amp;id=3bae64bd-e40f-807e-bf46-d67c3bafc08b&amp;t=3bae64bd-e40f-807e-bf46-d67c3bafc08b" alt="Vector 算子流水任务与数据通路" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">Vector 算子流水任务与数据通路</figcaption></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f805fb977c765ed6f5d9e" data-id="3bae64bde40f805fb977c765ed6f5d9e"><span><div id="3bae64bde40f805fb977c765ed6f5d9e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f805fb977c765ed6f5d9e" title="Init：完成多核切分与 Queue 初始化"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Init：完成多核切分与 Queue 初始化</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f802c810bf30d2b3e4928"><li>对于固定 Shape，可以在代码中预先计算：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f802c810bf30d2b3e4928"><li>总元素数 <code class="notion-inline-code">TOTAL_LENGTH</code>。</li><li>使用核数 <code class="notion-inline-code">BLOCK_DIM</code>。</li><li>单核处理元素数 <code class="notion-inline-code">BLOCK_LENGTH</code>。</li><li>单核内部 Tile 数 <code class="notion-inline-code">TILE_NUM</code>。</li><li>双缓冲数量 <code class="notion-inline-code">BUFFER_NUM = 2</code>。</li><li>单个 Tile 的元素数 <code class="notion-inline-code">TILE_LENGTH</code>。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80668fa5c46fe99b33c8"><li><code class="notion-inline-code">block_idx</code> 决定当前核在 Global Memory 中的起始偏移：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80668fa5c46fe99b33c8"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80779662ca414663e7d6"><li>之后用 <code class="notion-inline-code">SetGlobalBuffer()</code> 绑定当前核对应的 <code class="notion-inline-code">x/y/z</code> 数据区间，并用 <code class="notion-inline-code">pipe.InitBuffer()</code> 为 Queue 分配 Local Memory。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80dc8dbad7c425658706" data-id="3bae64bde40f80dc8dbad7c425658706"><span><div id="3bae64bde40f80dc8dbad7c425658706" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80dc8dbad7c425658706" title="Process：循环执行流水任务"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Process：循环执行流水任务</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80e4b108f5cf0b782d8b"><li><code class="notion-inline-code">Process()</code> 通常按 Progress 循环：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80e4b108f5cf0b782d8b"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f808bb436f2a2b7a23da3"><li>三个函数<span class="notion-red"><b>通过 Queue 建立数据依赖</b></span>。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3bae64bde40f80349820ca14d4091c61" data-id="3bae64bde40f80349820ca14d4091c61"><span><div id="3bae64bde40f80349820ca14d4091c61" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80349820ca14d4091c61" title="CopyIn"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">CopyIn</span></span></h5><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80728bb3df278bbd6d0a"><li>典型过程：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80728bb3df278bbd6d0a"><li><code class="notion-inline-code">AllocTensor()</code> 获得 LocalTensor。</li><li><code class="notion-inline-code">DataCopy()</code> 把当前 Tile 从 <code class="notion-inline-code">GlobalTensor</code> 搬入 LocalTensor。</li><li><code class="notion-inline-code">EnQue()</code> 把数据放入输入 Queue。</li></ul></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3bae64bde40f8090b405f1f0f7bef54b" data-id="3bae64bde40f8090b405f1f0f7bef54b"><span><div id="3bae64bde40f8090b405f1f0f7bef54b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8090b405f1f0f7bef54b" title="Compute"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Compute</span></span></h5><ul class="notion-list notion-list-disc notion-block-3bae64bde40f806e95c8e35fb11743c3"><li>典型过程：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f806e95c8e35fb11743c3"><li>从输入 Queue <code class="notion-inline-code">DeQue()</code> 取出 <code class="notion-inline-code">xLocal</code>、<code class="notion-inline-code">yLocal</code>。</li><li>从输出 Queue <code class="notion-inline-code">AllocTensor()</code> 获得 <code class="notion-inline-code">zLocal</code>。</li><li>调用 <code class="notion-inline-code">Add(zLocal, xLocal, yLocal, count)</code>。</li><li>将 <code class="notion-inline-code">zLocal</code> <code class="notion-inline-code">EnQue()</code> 到输出 Queue。</li><li>释放已经消费完的输入 LocalTensor。</li></ul></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3bae64bde40f80bfa087fd4f3ecb4caa" data-id="3bae64bde40f80bfa087fd4f3ecb4caa"><span><div id="3bae64bde40f80bfa087fd4f3ecb4caa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80bfa087fd4f3ecb4caa" title="CopyOut"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">CopyOut</span></span></h5><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80cdaa4ddd7a93b6993e"><li>典型过程：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80cdaa4ddd7a93b6993e"><li>从输出 Queue <code class="notion-inline-code">DeQue()</code> 取得 <code class="notion-inline-code">zLocal</code>。</li><li><code class="notion-inline-code">DataCopy()</code> 将结果写回 Global Memory。</li><li><code class="notion-inline-code">FreeTensor()</code> 释放输出 LocalTensor。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f802589a1ff90f3dc89a7" data-id="3bae64bde40f802589a1ff90f3dc89a7"><span><div id="3bae64bde40f802589a1ff90f3dc89a7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f802589a1ff90f3dc89a7" title="Double Buffer 机制"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Double Buffer 机制</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80e380a1d2c6f69ca199"><li>Double Buffer 的核心是为流水阶段<span class="notion-red"><b>准备两组可交替使用的缓冲区</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8083a06af65fce5794db"><li>没有 Double Buffer 时，一块 Local Memory 同时只能被一个阶段占用，CopyIn、Compute、CopyOut 容易互相等待。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80f88114ccfebe68970d"><li>采用双缓冲后：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80f88114ccfebe68970d"><li>当前 Tile 正在 Compute 时，可以为下一个 Tile 执行 CopyIn。</li><li>当前 Tile 正在 CopyOut 时，另一个 Tile 可以继续 Compute。</li><li>通过两个 Buffer 在不同 Stage 间轮换，降低硬件单元的空闲时间。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f805292a0c4d7d5f145a5"><li><span class="notion-red"><b>关键理解</b></span>：Double Buffer 不是把数据“多算一遍”，而是<span class="notion-red"><b>用额外一份片上缓冲换取更高的流水并行度</b></span>。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80d99d00e8bfea6cb766" data-id="3bae64bde40f80d99d00e8bfea6cb766"><span><div id="3bae64bde40f80d99d00e8bfea6cb766" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80d99d00e8bfea6cb766" title="1-4 运行验证"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1-4 运行验证</span></span></h3><ul class="notion-list notion-list-disc notion-block-3bae64bde40f801d9922d5bebda0a3e3"><li>一个完整的 Add Kernel 验证通常包括：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f801d9922d5bebda0a3e3"><li>生成输入数据。</li><li>分配输入、输出内存。</li><li>调用核函数。</li><li>将结果写出。</li><li>用 CPU/NumPy 等参考实现计算 Golden 结果。</li><li>比较设备结果和 Golden 结果。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a5ae75c96dac08aef9"><li>Kernel 直调示例既可以运行 CPU 仿真，也可以运行 NPU。<span class="notion-red"><b>CPU 模式</b></span>便于通过普通 C/C++ 调试方式<span class="notion-red"><b>定位逻辑问题</b></span>；<span class="notion-red"><b>NPU 模式</b></span>用于<span class="notion-red"><b>验证真实设备上的执行结果和性能行为</b></span>。</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3bae64bde40f808a94ecef34e4eccc57" data-id="3bae64bde40f808a94ecef34e4eccc57"><span><div id="3bae64bde40f808a94ecef34e4eccc57" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f808a94ecef34e4eccc57" title="2-Host侧实现"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2-Host侧实现</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80adadc2c9d0a6a7c98b" data-id="3bae64bde40f80adadc2c9d0a6a7c98b"><span><div id="3bae64bde40f80adadc2c9d0a6a7c98b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80adadc2c9d0a6a7c98b" title="2-1 Host 侧实现概述"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2-1 Host 侧实现概述</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80f5a859fa07ade5ccaa" data-id="3bae64bde40f80f5a859fa07ade5ccaa"><span><div id="3bae64bde40f80f5a859fa07ade5ccaa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80f5a859fa07ade5ccaa" title="Host 与 Device"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Host 与 Device</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80abbb08f370029ea703"><li>在典型昇腾算子运行环境中：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80abbb08f370029ea703"><li><span class="notion-red"><b>Host</b></span>：与 Device 相连的 x86/ARM 服务器，负责应用程序、运行时管理和 Host 侧算子逻辑。</li><li><span class="notion-red"><b>Device</b></span>：安装昇腾 AI 处理器的设备，通过 PCIe 等接口与 Host 连接，提供 NPU 计算能力。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8031b310fa1cc9683454"><li><span class="notion-red"><b>Kernel 负责 Device 侧计算</b></span>，而标准自定义算子还需要 Host 侧逻辑描述“怎么切、输出是什么、算子是什么”。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80cd904ff47fb6c45b5e" data-id="3bae64bde40f80cd904ff47fb6c45b5e"><span><div id="3bae64bde40f80cd904ff47fb6c45b5e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80cd904ff47fb6c45b5e" title="Host 侧三部分核心实现"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Host 侧三部分核心实现</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f803ba25ce85f4a09be71"><li>Host 侧主要包括：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f803ba25ce85f4a09be71"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f80519b74faab2c1c11d6" style="list-style-type:decimal"><li><span class="notion-red"><b>Tiling 实现</b></span>：根据输入 Shape、数据类型和硬件资源计算切分参数。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f80ec937fe85982f48cef" style="list-style-type:decimal"><li><span class="notion-red"><b>Shape 推导</b></span>：根据输入 Tensor 描述和算子属性推导输出 Tensor 描述。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f807b9ed9c9f17119fb92" style="list-style-type:decimal"><li><span class="notion-red"><b>算子原型注册</b></span>：定义输入、输出、数据类型、Format，并把 Tiling、Shape 推导等函数注册到算子。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8048af35fce2932d906d"><li>可以把三者理解为：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8048af35fce2932d906d"><li>算子原型注册：这个算子“是什么”。</li><li>Shape 推导：输出“长什么样”。</li><li>Tiling：运行时“怎么切、怎么并行”。</li></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f8099bb1ef5b3f61e8be6" data-id="3bae64bde40f8099bb1ef5b3f61e8be6"><span><div id="3bae64bde40f8099bb1ef5b3f61e8be6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8099bb1ef5b3f61e8be6" title="2-2 Tiling 下发"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2-2 Tiling 下发</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f809d9705ef2feca07641" data-id="3bae64bde40f809d9705ef2feca07641"><span><div id="3bae64bde40f809d9705ef2feca07641" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f809d9705ef2feca07641" title="为什么需要 Tiling"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">为什么需要 Tiling</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b084a5ccb2de73355c"><li>Local Memory 容量有限，通常无法一次放下算子的全部输入、输出数据。因此要把大 Tensor 切成多个较小的数据块，再分给多个核、多个 Tile 处理。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80568f3cc31175287817"><li>Tiling 的目标是确定：</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80adaac6e65753e09d55"><li>使用多少个 AI Core。</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80adaac6e65753e09d55"><li>每个核处理多少数据。</li><li>每个核内部再切成多少 Tile。</li><li>单个 Tile 的大小。</li><li>尾块如何处理。</li><li>需要多少额外 Workspace。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80338cc7d920d867d1c3"><li><span class="notion-red"><b>Tiling 通常在 Host CPU 上执行</b></span>，因为它主要进行 Shape、长度和硬件资源相关的标量计算，不适合占用 AI Core。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f803dafedd3b0e533b064" data-id="3bae64bde40f803dafedd3b0e533b064"><span><div id="3bae64bde40f803dafedd3b0e533b064" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f803dafedd3b0e533b064" title="Tiling 结构体"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Tiling 结构体</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8060b871f5d303987a8f"><li>Tiling 结果需要从 Host 传到 Kernel，因此需要一种双方都能理解的数据结构。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8075835dcc78465c1a32"><li>简单 Add 示例可以只包含：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8075835dcc78465c1a32"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f800b9c26fe732388dfa8"><li>标准自定义算子工程中通常通过 Tiling 宏定义数据字段，例如：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f800b9c26fe732388dfa8"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d0b838c385d04062e2"><li>Host 侧实例化并填充该结构，随后写入 Tiling Buffer；Kernel 侧读取同一份数据。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8023a4dac5d0c870ae68" data-id="3bae64bde40f8023a4dac5d0c870ae68"><span><div id="3bae64bde40f8023a4dac5d0c870ae68" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8023a4dac5d0c870ae68" title="Tiling 函数的工作流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Tiling 函数的工作流程</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80aca840d7d0e5e3013a"><li>Tiling 函数一般完成以下工作：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80aca840d7d0e5e3013a"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f801fbaffdf015c229490" style="list-style-type:decimal"><li>从 <code class="notion-inline-code">TilingContext</code> 获取输入 Tensor 的 Shape 等信息。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f803ba554d07592a1b646" style="list-style-type:decimal"><li>计算总元素数。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f802ea367d9e751648fd1" style="list-style-type:decimal"><li>决定 <code class="notion-inline-code">blockDim</code>，即启用多少个 AI Core。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3bae64bde40f8006963ad28337ffc33d" style="list-style-type:decimal"><li>计算单核数据量、Tile 数和 Tile 大小。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3bae64bde40f805fad1eee2b4861c667" style="list-style-type:decimal"><li>设置 Workspace 大小（如果算子需要）。</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3bae64bde40f80a18cacf79eb810b3a9" style="list-style-type:decimal"><li>把 TilingData 写入运行时提供的 Tiling Buffer。</li></ol><ol start="7" class="notion-list notion-list-numbered notion-block-3bae64bde40f8071b2f9ff95d541d062" style="list-style-type:decimal"><li>设置实际 TilingData 长度并返回成功。</li></ol></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f805ebfd2dfaca778e729" data-id="3bae64bde40f805ebfd2dfaca778e729"><span><div id="3bae64bde40f805ebfd2dfaca778e729" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f805ebfd2dfaca778e729" title="Kernel 侧读取 Tiling 信息"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Kernel 侧读取 Tiling 信息</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80068fe3ee691c2b1bc6"><li>标准核函数通常把 Tiling 信息放在参数列表尾部，例如：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80068fe3ee691c2b1bc6"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8093b1b1e9403fa48d6a"><li><span class="notion-red"><b>易错点</b></span>：标准工程中参数顺序通常按输入、输出、Workspace、Tiling 排列，不要随意调整。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80c39197d005e46a57e0" data-id="3bae64bde40f80c39197d005e46a57e0"><span><div id="3bae64bde40f80c39197d005e46a57e0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80c39197d005e46a57e0" title="固定 Shape 与动态 Shape"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">固定 Shape 与动态 Shape</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8004a110f191fa749d92"><li>固定 Shape 时，很多切分参数可以编译期写成常量；动态 Shape 时，这些值必须由 Host 在运行时计算并下发。</li></ul><table class="notion-simple-table notion-block-3bae64bde40f80779095e60bc8ee944f"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f8052903bca7270014e09"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">对比项</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">固定 Shape</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">动态 Shape</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80a081f1d78161a728f2"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">输入 Shape</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">编译前已确定</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">运行时变化</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80a4980fd2943b7b3426"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">切分参数</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">可写为静态常量</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">需要由 Tiling 计算</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80d0a2b1e4b0aff6a0ea"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">Kernel 中的数据长度</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">常量</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">成员变量 / TilingData</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f805e8655f8032fd2107b"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">灵活性</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">低</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">高</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f802d91a8df2c6b7cf8be"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">Host 工作量</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">较少</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">较多</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80baa855e19067aae530"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">调优空间</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">针对固定输入优化</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">需要兼顾多种 Shape</div></td></tr></tbody></table><ul class="notion-list notion-list-disc notion-block-3bae64bde40f803e8efcec27440301dd"><li><span class="notion-red"><b>动态 Shape 改造</b></span>的核心可以概括成：<span class="notion-red"><b>静态常量 → 由 Tiling 下发的成员变量</b></span></li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80c39517dcff35e35ac6"><li>例如原来 Kernel 中写死的 <code class="notion-inline-code">BLOCK_LENGTH</code>、<code class="notion-inline-code">TILE_NUM</code>，动态 Shape 下应从 <code class="notion-inline-code">tilingData</code> 得到。</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3bae64bde40f80bf8f9fea9068653477"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3Ac2a60dea-4e7a-4920-b126-3e78d85d23ae%3A%E5%8A%A8%E6%80%81_Shape_%E7%9A%84_Tiling_%E5%88%87%E5%88%86%E7%A4%BA%E6%84%8F.png?table=block&amp;id=3bae64bd-e40f-80bf-8f9f-ea9068653477&amp;t=3bae64bd-e40f-80bf-8f9f-ea9068653477" alt="动态 Shape 的 Tiling 切分示意" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">动态 Shape 的 Tiling 切分示意</figcaption></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80298514d4050a550800" data-id="3bae64bde40f80298514d4050a550800"><span><div id="3bae64bde40f80298514d4050a550800" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80298514d4050a550800" title="固定 Shape 与动态 Shape 工程文件差异"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">固定 Shape 与动态 Shape 工程文件差异</span></span></h4><table class="notion-simple-table notion-block-3bae64bde40f80069eb2d351ad0b67fa"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f8069a5ffcd00869abe05"><td class="" style="width:176.75px"><div class="notion-simple-table-cell">文件</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">主要职责</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">固定 Shape</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">动态 Shape</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80fca3b5cb917932ef88"><td class="" style="width:176.75px"><div class="notion-simple-table-cell"><code class="notion-inline-code">main.cpp</code></div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">Host 测试程序、内存申请、任务下发</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">读取固定输入即可</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">需要准备并下发 Tiling 信息</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8023be4fe77e1b678898"><td class="" style="width:176.75px"><div class="notion-simple-table-cell"><code class="notion-inline-code">add_custom.cpp</code></div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">Ascend C Kernel 实现</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">Shape 参数常量化</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">从 Tiling 获取切分参数</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80739a93dc292db3b070"><td class="" style="width:176.75px"><div class="notion-simple-table-cell"><code class="notion-inline-code">add_custom.py</code></div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">输入和 Golden 数据生成</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">生成固定 Shape 数据</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">同时生成对应 Tiling 数据/动态输入</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f805496f7d21986081ab8"><td class="" style="width:176.75px"><div class="notion-simple-table-cell"><code class="notion-inline-code">CMakeLists.txt</code></div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">工程编译配置</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">基本不变</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">基本不变</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80a69929c5feb7d1d634"><td class="" style="width:176.75px"><div class="notion-simple-table-cell"><code class="notion-inline-code">data_utils.h</code></div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">Host 数据读写等辅助能力</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">基本不变</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">基本不变</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f806290e1c24e9e502a3e"><td class="" style="width:176.75px"><div class="notion-simple-table-cell"><code class="notion-inline-code">run.sh</code></div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">一键运行脚本</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">基本不变</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">基本不变</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8057b995cc9fb8bd96c1"><td class="" style="width:176.75px"><div class="notion-simple-table-cell"><code class="notion-inline-code">add_custom_tiling.h</code></div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">Tiling 数据结构</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">可以不涉及</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">定义/解析 Tiling 数据</div></td></tr></tbody></table><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f8042a319e4c95759f7de" data-id="3bae64bde40f8042a319e4c95759f7de"><span><div id="3bae64bde40f8042a319e4c95759f7de" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8042a319e4c95759f7de" title="2-3 Shape 推导"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2-3 Shape 推导</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80939249ee26f84ffaaa" data-id="3bae64bde40f80939249ee26f84ffaaa"><span><div id="3bae64bde40f80939249ee26f84ffaaa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80939249ee26f84ffaaa" title="Shape 推导的意义"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Shape 推导的意义</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a6a842eabf9516da0b"><li><span class="notion-red"><b>神经网络</b></span>可以看作一个<span class="notion-red"><b>有向无环计算图</b></span>，<span class="notion-red"><b>每一个结点都是一个算子</b></span>。当前算子的输出通常又会作为后续算子的输入，因此运行前需要尽可能确定每个输出 Tensor 的描述信息。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8096b385eb2e85d2a525"><li>Shape 推导根据：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8096b385eb2e85d2a525"><li>输入 Tensor 的 Shape。</li><li>输入 Tensor 的数据类型、Format。</li><li>算子属性。</li><li>算子的数学语义。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f809b94f0c69eeeb4909e"><li>推导输出 Tensor 的 Shape 等信息。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8010a114e391025e7212" data-id="3bae64bde40f8010a114e391025e7212"><span><div id="3bae64bde40f8010a114e391025e7212" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8010a114e391025e7212" title="Shape 推导的作用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Shape 推导的作用</span></span></h4><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f80289a80d7bc92630fa3" style="list-style-type:decimal"><li><span class="notion-red"><b>参数校验</b></span>：尽早发现输入不满足算子约束的问题。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f803288e2f4cabdf14035" style="list-style-type:decimal"><li><span class="notion-red"><b>输出描述推导</b></span>：确定输出 Shape、dtype、Format 等信息。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f8030b6becf2897277143" style="list-style-type:decimal"><li><span class="notion-red"><b>静态内存规划</b></span>：计算图构建阶段即可为已知 Tensor 分配内存，减少运行时动态分配开销。</li></ol><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8060b403fb4e4dfbc0db"><li>对于逐元素 Add，如果输入 <code class="notion-inline-code">x</code>、<code class="notion-inline-code">y</code> Shape 已经满足广播/匹配要求，最简单场景下输出 Shape 与输入 Shape 相同。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d095bccd0b06e14a03"><li>概念代码：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d095bccd0b06e14a03"></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f803eb743f256279c494e" data-id="3bae64bde40f803eb743f256279c494e"><span><div id="3bae64bde40f803eb743f256279c494e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f803eb743f256279c494e" title="2-4 原型注册"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2-4 原型注册</span></span></h3><ul class="notion-list notion-list-disc notion-block-3bae64bde40f803ebd21fbfe963dceb6"><li><span class="notion-red"><b>算子原型注册</b></span>用于完整描述算子的“接口契约”，主要包括：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f803ebd21fbfe963dceb6"><li>算子名称。</li><li>输入名称与数量。</li><li>输出名称与数量。</li><li>参数是否必选。</li><li>支持的数据类型。</li><li>支持的 Format。</li><li>Shape 推导函数。</li><li>Tiling 函数。</li><li>对应的 AI Core / SoC 配置。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80718193e1867027da42"><li>Add 示例可抽象为：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80718193e1867027da42"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8003857ce34cd6db93df"><li>Host 侧原型、Shape 推导与 Tiling 最终在同一个算子定义中关联起来，使框架能够完成算子发现、校验、编译与运行。</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3bae64bde40f80bd8e1cc25b3fa3b5c7" data-id="3bae64bde40f80bd8e1cc25b3fa3b5c7"><span><div id="3bae64bde40f80bd8e1cc25b3fa3b5c7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80bd8e1cc25b3fa3b5c7" title="3-算子开发工程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3-算子开发工程</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80d79923cc0fad78bf9d" data-id="3bae64bde40f80d79923cc0fad78bf9d"><span><div id="3bae64bde40f80d79923cc0fad78bf9d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80d79923cc0fad78bf9d" title="3-1 算子开发工程概述"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3-1 算子开发工程概述</span></span></h3><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8034a3b2fb11018be63f"><li>Kernel 和 Host 都写完后，还需要解决四个工程问题：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8034a3b2fb11018be63f"><li>怎样组织代码和目录？</li><li>怎样编译 Kernel 与 Host？</li><li>怎样生成可安装的算子包？</li><li>怎样部署到运行环境？</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f807fbeeed4e603c3f3d0"><li>Ascend C 提供<span class="notion-red"><b>两种典型开发工程</b></span>。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80d5ae28e9de6cd151e2" data-id="3bae64bde40f80d5ae28e9de6cd151e2"><span><div id="3bae64bde40f80d5ae28e9de6cd151e2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80d5ae28e9de6cd151e2" title="Kernel 直调工程：快速流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Kernel 直调工程：快速流程</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80e2b663e2913a4e4491"><li>适合：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80e2b663e2913a4e4491"><li>学习 Ascend C Kernel。</li><li>快速验证算法逻辑。</li><li>调试 Kernel。</li><li>不希望先编写完整 Host 侧标准算子工程。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f802b9159e1ebd8e87ae4"><li>特点：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f802b9159e1ebd8e87ae4"><li>文件少。</li><li>开发周期短。</li><li>Kernel 开发完成后可以直接写 Host 测试程序调用。</li><li>Tiling 可以简单处理，不依赖完整 CANN 标准算子注册流程。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80f2b7aed60b9fc90cec" data-id="3bae64bde40f80f2b7aed60b9fc90cec"><span><div id="3bae64bde40f80f2b7aed60b9fc90cec" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80f2b7aed60b9fc90cec" title="自定义算子工程：标准流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">自定义算子工程：标准流程</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80fab0fdd42d12d1e1b7"><li>适合：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80fab0fdd42d12d1e1b7"><li>正式开发可部署算子。</li><li>需要框架调用。</li><li>需要 Host 侧原型注册、Shape 推导、Tiling。</li><li>需要生成算子安装包。</li><li>后续需要通过 AscendCL、PyTorch Adapter 等方式调用。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d4848aca14532a51f5"><li>特点：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d4848aca14532a51f5"><li>工程文件更多。</li><li>开发流程更完整。</li><li>可以通过工程脚本统一完成编译、打包和部署。</li></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80109de7de4bfb57b774" data-id="3bae64bde40f80109de7de4bfb57b774"><span><div id="3bae64bde40f80109de7de4bfb57b774" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80109de7de4bfb57b774" title="3-2 快速流程——Kernel 直调工程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3-2 快速流程——Kernel 直调工程</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80ab9a87f2fe14152259" data-id="3bae64bde40f80ab9a87f2fe14152259"><span><div id="3bae64bde40f80ab9a87f2fe14152259" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80ab9a87f2fe14152259" title="Kernel 直调的核心思想"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Kernel 直调的核心思想</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80f79ccbde9560f2e79b"><li>Kernel 直调就是：<span class="notion-red"><b>Kernel 写完后，不先构建完整自定义算子包，而是直接写一个 Host 测试程序调用核函数</b></span><b>。</b></li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a68775c9d6a1917d83"><li>最简工程只需要：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a68775c9d6a1917d83"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a682b4d552e25f32cc"><li>为了形成完整的自动验证流程，通常进一步加入：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a682b4d552e25f32cc"></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8043a421d0754dd21284" data-id="3bae64bde40f8043a421d0754dd21284"><span><div id="3bae64bde40f8043a421d0754dd21284" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8043a421d0754dd21284" title="CPU 与 NPU 两种验证路径"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">CPU 与 NPU 两种验证路径</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80ccb8c8d26b4a0ab07e"><li>Kernel 直调支持两类运行方式：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80ccb8c8d26b4a0ab07e"><li><span class="notion-red"><b>CPU 调测</b></span>：使用 CPU 仿真相关接口，例如 <code class="notion-inline-code">ICPU_RUN_KF</code>，适合快速调试逻辑。</li><li><span class="notion-red"><b>NPU 调测</b></span>：使用核函数调用语法或 AscendCL Runtime API，在真实 NPU 上执行。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80e097f3f86e3cd28271"><li>CPU 调测可以使用常规 C/C++ 手段，例如：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80e097f3f86e3cd28271"><li><code class="notion-inline-code">gdb</code></li><li><code class="notion-inline-code">printf</code></li><li><code class="notion-inline-code">std::cout</code></li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80138bd5ceaed5dce5de"><li>NPU 调测更关注：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80138bd5ceaed5dce5de"><li><code class="notion-inline-code">printf</code></li><li><code class="notion-inline-code">DumpTensor</code></li><li>真实硬件行为与执行结果</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f801fb00aebbcda81a1d5" data-id="3bae64bde40f801fb00aebbcda81a1d5"><span><div id="3bae64bde40f801fb00aebbcda81a1d5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f801fb00aebbcda81a1d5" title="run.sh 的典型流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">run.sh 的典型流程</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f800da8edf19917c53499"><li>Kernel 直调的价值在于<span class="notion-red"><b>减少工程噪声，让开发者先集中验证 Kernel 本身</b></span>。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f803295e4e7863b80235b" data-id="3bae64bde40f803295e4e7863b80235b"><span><div id="3bae64bde40f803295e4e7863b80235b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f803295e4e7863b80235b" title="3-3 标准流程——自定义算子工程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3-3 标准流程——自定义算子工程</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80f1bba1fd694713de09" data-id="3bae64bde40f80f1bba1fd694713de09"><span><div id="3bae64bde40f80f1bba1fd694713de09" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80f1bba1fd694713de09" title="标准流程与快速流程对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">标准流程与快速流程对比</span></span></h4><table class="notion-simple-table notion-block-3bae64bde40f80d99204f48d84456887"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f807eae4dc0d832d6fb17"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">项目</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">快速开发模式</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">标准开发模式</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8040ab8bf0437c1d4a13"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">代码文件</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">少</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">多</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f805baa0be2e2aceb63a9"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">开发周期</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">短</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">长</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80aa9da1d8e5626aa775"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">Host 侧实现</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">简化</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">完整：原型、Shape、Tiling 等</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80bcbf4bcabfcf668be3"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">调用方式</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">Kernel 直调</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">单算子 API / 模型 / 框架调用</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8045adf1fd1079d629c0"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">适用阶段</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">学习、验证、快速调试</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">正式集成、部署和发布</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8040bf2bde85e675f6cf"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">推荐顺序</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">先</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">后</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f804e9621e0a358f10034" data-id="3bae64bde40f804e9621e0a358f10034"><span><div id="3bae64bde40f804e9621e0a358f10034" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f804e9621e0a358f10034" title="Add 算子分析"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Add 算子分析</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a98925f574b5b5b16b"><li>Add 的数学表达式：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a98925f574b5b5b16b"><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f807a9312d9f83741f2f9"><li>实现时需要明确：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f807a9312d9f83741f2f9"><li>输入：<code class="notion-inline-code">x</code>、<code class="notion-inline-code">y</code>。</li><li>输出：<code class="notion-inline-code">z</code>。</li><li>示例 dtype：<code class="notion-inline-code">half</code>。</li><li>示例 Shape：<code class="notion-inline-code">(8, 2048)</code>。</li><li>示例 Format：<code class="notion-inline-code">ND</code>。</li><li>搬运 API：<code class="notion-inline-code">DataCopy</code>。</li><li>计算 API：<code class="notion-inline-code">Add</code>。</li><li>内部数据对象：<code class="notion-inline-code">LocalTensor</code>。</li><li>流水管理：<code class="notion-inline-code">Queue</code>、<code class="notion-inline-code">EnQue</code>、<code class="notion-inline-code">DeQue</code>。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f804696d4fa20274a3acf" data-id="3bae64bde40f804696d4fa20274a3acf"><span><div id="3bae64bde40f804696d4fa20274a3acf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f804696d4fa20274a3acf" title="使用 msopgen 创建算子工程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">使用 msopgen 创建算子工程</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d3b54ac834fa333eac"><li>CANN 提供 <code class="notion-inline-code">msopgen</code> 工具，可根据算子描述 JSON 自动生成标准工程骨架。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f806eb630ebaa826d5edb"><li>基本步骤：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f806eb630ebaa826d5edb"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f8041b765de77a340a101" style="list-style-type:decimal"><li>编写算子描述 JSON。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f80058071ebd7fc0eb001" style="list-style-type:decimal"><li>使用 <code class="notion-inline-code">msopgen</code> 生成工程。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f80258355d991644067d0" style="list-style-type:decimal"><li>在生成的 Kernel 目录中完成设备侧实现。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3bae64bde40f8075994dcd96ec620f01" style="list-style-type:decimal"><li>在 Host 目录中完成原型、Shape 推导和 Tiling。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3bae64bde40f804abe60fa3a625c2b4a" style="list-style-type:decimal"><li>编译并生成安装包。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f804fb07ccec8d7272922"><li>算子描述 JSON 重点包含：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f804fb07ccec8d7272922"><li>算子名称。</li><li>输入列表。</li><li>输出列表。</li><li>Shape/Format 约束。</li><li>dtype 约束。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80a98330d5aae44fa03c" data-id="3bae64bde40f80a98330d5aae44fa03c"><span><div id="3bae64bde40f80a98330d5aae44fa03c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80a98330d5aae44fa03c" title="标准工程的主要目录"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">标准工程的主要目录</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8059a3b9c1c121e91d3e"><li>标准工程一般可以概括为：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8059a3b9c1c121e91d3e"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8078b4d5e80051a27c4b"><li>Kernel 与 Host 被分别编译，随后由工程脚本打包成自定义算子安装包。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8041bc51d34eea25eee4" data-id="3bae64bde40f8041bc51d34eea25eee4"><span><div id="3bae64bde40f8041bc51d34eea25eee4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8041bc51d34eea25eee4" title="Kernel 侧实现"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Kernel 侧实现</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a0bf12f9eef96767a5"><li>标准工程中的 Kernel 仍然遵循：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a0bf12f9eef96767a5"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f805d9499d63108be2eb9"><li>与快速工程的主要区别不是计算逻辑本身，而是：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f805d9499d63108be2eb9"><li>切分参数从 TilingData 获取。</li><li>Kernel 与 Host 原型建立正式关联。</li><li>编译产物进入自定义算子包。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80ad814ed4de52e18697" data-id="3bae64bde40f80ad814ed4de52e18697"><span><div id="3bae64bde40f80ad814ed4de52e18697" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80ad814ed4de52e18697" title="Host 侧 TilingData 定义"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Host 侧 TilingData 定义</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8069bd9cd9aa71e72542"><li>标准工程中可通过宏定义 TilingData：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8069bd9cd9aa71e72542"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d483f3e786f2843cfb"><li>随后注册 TilingData 类型，并由 Host 的 Tiling 函数填充。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f805fa7cee315ac476399" data-id="3bae64bde40f805fa7cee315ac476399"><span><div id="3bae64bde40f805fa7cee315ac476399" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f805fa7cee315ac476399" title="工程编译"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">工程编译</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8094b869ca68ff21acd4"><li>编译阶段主要完成：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8094b869ca68ff21acd4"><li>Kernel 源码编译。</li><li>Host 源码编译。</li><li>Tiling / 原型相关代码编译。</li><li>生成自定义算子安装包 <code class="notion-inline-code">.run</code>。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8019bb59cca386c8d878"><li>常见 CMake 配置项包括：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8019bb59cca386c8d878"><table class="notion-simple-table notion-block-3bae64bde40f80ac918fde1019ef565d"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f804095d8d1d51ea288d8"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">配置项</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">作用</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80df933ad0bd837eceab"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">ASCEND_CANN_PACKAGE_PATH</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">指定 CANN 安装路径</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80418a75f5014effa82d"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">CMAKE_BUILD_TYPE</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Release</code> / <code class="notion-inline-code">Debug</code> 等构建类型</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80e795b4efe9fad463c2"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">ENABLE_SOURCE_PACKAGE</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">是否生成源码相关包</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80e18f83e1da1de0b036"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">ENABLE_BINARY_PACKAGE</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">是否生成二进制相关包</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80bdb7f0dc0f7533647e"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">vendor_name</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">自定义算子厂商/包命名信息</div></td></tr></tbody></table></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a0a914e88563fe08d3"><li>工程通常通过 <code class="notion-inline-code">build.sh</code> 完成构建，并在 <code class="notion-inline-code">build_out</code> 等目录生成安装包。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80a8bb08f07335230045" data-id="3bae64bde40f80a8bb08f07335230045"><span><div id="3bae64bde40f80a8bb08f07335230045" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80a8bb08f07335230045" title="算子包部署"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">算子包部署</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8074a6d4dfbd6c662e13"><li>编译完成后执行生成的 <code class="notion-inline-code">.run</code> 安装包，将自定义算子部署到目标环境。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f805b9136ec712fab5ad7"><li>部署后的文件通常按功能分布到：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f805b9136ec712fab5ad7"><li>Host 配置与算子原型相关目录。</li><li>Kernel 二进制/源码相关目录。</li><li>Tiling、配置、版本等辅助目录。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8058926bc0007e3bf7fe"><li>这样运行时和框架才能发现并加载自定义算子。</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3bae64bde40f8077bf4dec27e9ec3f50" data-id="3bae64bde40f8077bf4dec27e9ec3f50"><span><div id="3bae64bde40f8077bf4dec27e9ec3f50" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8077bf4dec27e9ec3f50" title="4-API通用解读"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4-API通用解读</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80039e2fe5e8d9e54b85" data-id="3bae64bde40f80039e2fe5e8d9e54b85"><span><div id="3bae64bde40f80039e2fe5e8d9e54b85" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80039e2fe5e8d9e54b85" title="4-1 Ascend C 编程 API 概述"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4-1 Ascend C 编程 API 概述</span></span></h3><div class="notion-text notion-block-3bae64bde40f80278e2df7878cc9a0e0">Ascend C API 可以按抽象层次分为两类：</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f803dbe8ac640aa538441" data-id="3bae64bde40f803dbe8ac640aa538441"><span><div id="3bae64bde40f803dbe8ac640aa538441" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f803dbe8ac640aa538441" title="基础 API"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">基础 API</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f803aad83c2a7e107645c"><li><span class="notion-red"><b>基础 API </b></span>更贴近硬件能力，主要包括：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f803aad83c2a7e107645c"><li>计算 API。</li><li>数据搬运 API。</li><li>内存管理 API。</li><li>任务同步 API。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f802f8c63c8509bb45b62"><li>基础 API 的输入输出通常围绕 <code class="notion-inline-code">GlobalTensor</code> 与 <code class="notion-inline-code">LocalTensor</code> 展开，灵活度高，适合自己设计数据通路和计算过程。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8073bb79e153a2433780" data-id="3bae64bde40f8073bb79e153a2433780"><span><div id="3bae64bde40f8073bb79e153a2433780" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8073bb79e153a2433780" title="高阶 API"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">高阶 API</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f800a9768c4594ff89588"><li><span class="notion-red"><b>高阶 API </b></span>对常见复杂算法进行进一步封装，例如：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f800a9768c4594ff89588"><li>Matmul。</li><li>Softmax。</li><li>Sinh 等数学函数。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f805788cfef64cc0f122a"><li>使用高阶 API 可以减少重复开发，但<span class="notion-red"><b>通常需要根据接口要求准备临时空间</b></span>、<span class="notion-red"><b>参数对象</b></span>或<span class="notion-red"><b>初始化流程</b></span>。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80ed93d1f7494eb9a52e" data-id="3bae64bde40f80ed93d1f7494eb9a52e"><span><div id="3bae64bde40f80ed93d1f7494eb9a52e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80ed93d1f7494eb9a52e" title="4-2 基础 API"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4-2 基础 API</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f805185e2f85794428b0e" data-id="3bae64bde40f805185e2f85794428b0e"><span><div id="3bae64bde40f805185e2f85794428b0e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f805185e2f85794428b0e" title="基础 API 四大类"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">基础 API 四大类</span></span></h4><table class="notion-simple-table notion-block-3bae64bde40f801caf9aebbbcc152535"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f805d9b5ade8d681dc6db"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">API 类型</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">作用</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">常见接口</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80678090ea2e01476590"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">计算 API</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">在 Local Memory 上完成计算</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Add</code> 等 Vector API</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8003ab85df13d5801466"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">数据搬运 API</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">在不同存储位置之间搬运数据</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell"><code class="notion-inline-code">DataCopy</code></div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80f8a3cadd89f021dc0a"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">内存管理 API</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">管理 Local Memory / Queue 缓冲</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell"><code class="notion-inline-code">InitBuffer</code>、<code class="notion-inline-code">AllocTensor</code>、<code class="notion-inline-code">FreeTensor</code></div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8036bf7fe5c19ad9c1fa"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">任务同步 API</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">管理流水任务的数据依赖</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell"><code class="notion-inline-code">EnQue</code>、<code class="notion-inline-code">DeQue</code></div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80e98112ef4bc9cdb6e7" data-id="3bae64bde40f80e98112ef4bc9cdb6e7"><span><div id="3bae64bde40f80e98112ef4bc9cdb6e7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80e98112ef4bc9cdb6e7" title="计算 API 的三种使用层次"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">计算 API 的三种使用层次</span></span></h4><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3bae64bde40f801792b6e1bd6af7daaa" data-id="3bae64bde40f801792b6e1bd6af7daaa"><span><div id="3bae64bde40f801792b6e1bd6af7daaa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f801792b6e1bd6af7daaa" title="整个 Tensor 参与计算"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">整个 Tensor 参与计算</span></span></h5><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8078b30dcf7f4a4390db"><li>最简单的写法直接对整个 LocalTensor 计算，例如：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8078b30dcf7f4a4390db"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f807bb6efd1f431252569"><li>适合连续数据和简单逐元素计算。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3bae64bde40f802ba7b4fd317ff1b72f" data-id="3bae64bde40f802ba7b4fd317ff1b72f"><span><div id="3bae64bde40f802ba7b4fd317ff1b72f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f802ba7b4fd317ff1b72f" title="Tensor 前 N 个元素参与计算"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Tensor 前 N 个元素参与计算</span></span></h5><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8013ab74e35fecdaaa00"><li>当只需要处理当前 Tile 中的部分有效数据时，可以通过 <code class="notion-inline-code">count</code> 控制实际元素数。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3bae64bde40f80608e0ae26bf07e1999" data-id="3bae64bde40f80608e0ae26bf07e1999"><span><div id="3bae64bde40f80608e0ae26bf07e1999" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80608e0ae26bf07e1999" title="Tensor 高维切分计算"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Tensor 高维切分计算</span></span></h5><ul class="notion-list notion-list-disc notion-block-3bae64bde40f808e9ebffeb6c60a4dd7"><li>更复杂的 Vector API 可以通过以下参数控制多轮计算：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f808e9ebffeb6c60a4dd7"><li><code class="notion-inline-code">repeatTimes</code></li><li><code class="notion-inline-code">repeatStride</code></li><li><code class="notion-inline-code">blockStride</code></li><li><code class="notion-inline-code">mask</code></li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8022b91ad4e94264deeb"><li>它们用于表达跨 block、跨 repeat 的规则访问方式。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f805883e0c17ac41deee6" data-id="3bae64bde40f805883e0c17ac41deee6"><span><div id="3bae64bde40f805883e0c17ac41deee6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f805883e0c17ac41deee6" title="repeatTimes"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">repeatTimes</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8041b87ee16826addf96"><li>Vector 计算单元一次 Repeat 可处理若干连续 block。典型向量场景中：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8041b87ee16826addf96"><li>一个 block 为 32 Byte。</li><li>一次 Repeat 可覆盖 8 个 block，即 256 Byte。</li><li>数据超过一次 Repeat 的容量时，通过 <code class="notion-inline-code">repeatTimes</code> 增加重复次数。</li><li><code class="notion-inline-code">repeatTimes</code> 的有效范围存在上限，设计 Tile 时要避免单次调用超过接口限制。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8069866de599813a25d8"><li>例如 16 个 block 的连续数据，可分成 2 次 Repeat 处理。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80e7b57ac69355f2dcbc" data-id="3bae64bde40f80e7b57ac69355f2dcbc"><span><div id="3bae64bde40f80e7b57ac69355f2dcbc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80e7b57ac69355f2dcbc" title="repeatStride"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">repeatStride</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f806ba10ff36db3c6a890"><li><code class="notion-inline-code">repeatStride</code> 描述<b>相邻 Repeat 起始位置之间的地址跨度</b>。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f809bb96fcf074b79705b"><li>常见用途：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f809bb96fcf074b79705b"><li>连续计算：下一个 Repeat 紧接上一个 Repeat。</li><li>间隔计算：不同 Repeat 之间存在空洞。</li><li>重复计算：stride 为 0 时，可反复读取同一片数据。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8063be3ec0958e0a793c" data-id="3bae64bde40f8063be3ec0958e0a793c"><span><div id="3bae64bde40f8063be3ec0958e0a793c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8063be3ec0958e0a793c" title="blockStride"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">blockStride</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8076a561c255038b72e6"><li><code class="notion-inline-code">blockStride</code> 描述<b>同一次 Repeat 内不同 block 之间的地址跨度</b>。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8012bef0d5da43148654"><li>因此要区分：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8012bef0d5da43148654"></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8072800ef82cfea1837f" data-id="3bae64bde40f8072800ef82cfea1837f"><span><div id="3bae64bde40f8072800ef82cfea1837f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8072800ef82cfea1837f" title="Mask：连续模式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Mask：连续模式</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f804fa5cbd12f84a003f4"><li>Mask 决定一次向量指令中哪些元素真正参与计算。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f809d9a3acb61850ca2d2"><li>连续模式直接指定前多少个元素有效：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f809d9a3acb61850ca2d2"><li>16 bit 数据单次可覆盖的元素数更多。</li><li>32 bit 数据单次可覆盖的元素数相应减少。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80619571dc49aaa203a6"><li>适合“前 N 个元素有效”的场景。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80919af6cf2b8eadde21" data-id="3bae64bde40f80919af6cf2b8eadde21"><span><div id="3bae64bde40f80919af6cf2b8eadde21" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80919af6cf2b8eadde21" title="Mask：逐 bit 模式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Mask：逐 bit 模式</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80039daffbd96156ed1d"><li>逐 bit Mask 用位图描述元素是否参与计算：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80039daffbd96156ed1d"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8080b17ef7dee3d468d1"><li>适合非连续选取元素的场景。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80269726ef5c67544bfd"><li><span class="notion-red"><b>理解重点</b></span>：<code class="notion-inline-code">repeatTimes / repeatStride / blockStride / mask</code> 共同描述一次 Vector API 如何在 Local Memory 中“走地址”。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f806b9291e89309206aff" data-id="3bae64bde40f806b9291e89309206aff"><span><div id="3bae64bde40f806b9291e89309206aff" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f806b9291e89309206aff" title="数据搬运 API：DataCopy"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">数据搬运 API：DataCopy</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8061b90efb61b910f69a"><li>常见搬运方向包括：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8061b90efb61b910f69a"><li>GM → Vector 输入区。</li><li>Vector 输出区 → GM。</li><li>GM → Cube 输入相关位置。</li><li>Cube 计算结果位置 → GM。</li><li>不同片上逻辑位置之间的搬运。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8041adabf2ef4de3b41c"><li>对于最常见的连续数据：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8041adabf2ef4de3b41c"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f805ebac9f555ec650867"><li>复杂二维/跨步搬运可以使用 <code class="notion-inline-code">DataCopyParams</code>。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80cbb886d8059c113f33" data-id="3bae64bde40f80cbb886d8059c113f33"><span><div id="3bae64bde40f80cbb886d8059c113f33" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80cbb886d8059c113f33" title="DataCopyParams"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">DataCopyParams</span></span></h4><table class="notion-simple-table notion-block-3bae64bde40f802696ecec4428ce520b"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f80c98d0ac6014d66683d"><td class="" style="width:353.5px"><div class="notion-simple-table-cell">参数</div></td><td class="" style="width:353.5px"><div class="notion-simple-table-cell">含义</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80c5bc7cf337286a57b1"><td class="" style="width:353.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">blockCount</code></div></td><td class="" style="width:353.5px"><div class="notion-simple-table-cell">连续搬运的数据块数量</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8059b164f4051afb20bd"><td class="" style="width:353.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">blockLen</code></div></td><td class="" style="width:353.5px"><div class="notion-simple-table-cell">每个数据块的长度，通常以 32 Byte data block 为单位</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80ee94a0e1a4b0b0ff97"><td class="" style="width:353.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">srcStride</code></div></td><td class="" style="width:353.5px"><div class="notion-simple-table-cell">源侧相邻数据块之间需要跳过的间隔</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80f5b811ca81a19576e2"><td class="" style="width:353.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">dstStride</code></div></td><td class="" style="width:353.5px"><div class="notion-simple-table-cell">目的侧相邻数据块之间需要跳过的间隔</div></td></tr></tbody></table><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80318314d51a7810bc72"><li>可以把二维搬运理解成：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80318314d51a7810bc72"></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80a7a113f8eb7ce025ab" data-id="3bae64bde40f80a7a113f8eb7ce025ab"><span><div id="3bae64bde40f80a7a113f8eb7ce025ab" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80a7a113f8eb7ce025ab" title="内存管理 API"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">内存管理 API</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80818b29f398f4e065df"><li><code class="notion-inline-code">TPipe</code> 负责管理片上内存资源，<code class="notion-inline-code">TQue</code> 表示某个流水阶段使用的 Queue。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8010b968c970e3180973"><li>典型流程：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8010b968c970e3180973"></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f807895b1d316b5681ac1" data-id="3bae64bde40f807895b1d316b5681ac1"><span><div id="3bae64bde40f807895b1d316b5681ac1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f807895b1d316b5681ac1" title="EnQue / DeQue"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">EnQue / DeQue</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8063bd7dc44466f8cd60"><li><code class="notion-inline-code">EnQue()</code> 与 <code class="notion-inline-code">DeQue()</code> 不只是普通容器操作，而是流水阶段间的同步机制。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b3b22bd282d2b070b7"><li>Producer 把准备好的 Tensor 放入 Queue，Consumer 在数据可用后取出，从而维持 Stage 之间正确的数据依赖关系。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f8005a58bfbaa7ce8b3c7" data-id="3bae64bde40f8005a58bfbaa7ce8b3c7"><span><div id="3bae64bde40f8005a58bfbaa7ce8b3c7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8005a58bfbaa7ce8b3c7" title="4-3 高阶 API"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4-3 高阶 API</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f801f874bc2d4b1ddf636" data-id="3bae64bde40f801f874bc2d4b1ddf636"><span><div id="3bae64bde40f801f874bc2d4b1ddf636" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f801f874bc2d4b1ddf636" title="高阶 API 的价值"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">高阶 API 的价值</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f807fa089e438b3d0f41a"><li>高阶 API 封装了常见算法的复杂实现。以 Matmul 为例，开发者通常只需要：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f807fa089e438b3d0f41a"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f8095aeb2c7b1f5882cf1" style="list-style-type:decimal"><li>创建 Matmul 对象。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f8075bcf4c598b59218e2" style="list-style-type:decimal"><li>初始化。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f80a0af1bf5c9ee6f4359" style="list-style-type:decimal"><li>设置左矩阵 A。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3bae64bde40f80169111c2795fdde32a" style="list-style-type:decimal"><li>设置右矩阵 B 和 Bias 等参数。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3bae64bde40f80e099a3c78fc7b21cc8" style="list-style-type:decimal"><li>执行矩阵乘。</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3bae64bde40f80279ccef045e65f0a5b" style="list-style-type:decimal"><li>结束计算。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80c8b75fdcb952f417ce"><li>相比手工组织 Cube 指令、搬运和同步，<span class="notion-red"><b>高阶 API 可以显著减少代码量</b></span>。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8062b764f01525f5e97e" data-id="3bae64bde40f8062b764f01525f5e97e"><span><div id="3bae64bde40f8062b764f01525f5e97e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8062b764f01525f5e97e" title="高阶 API 的临时空间"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">高阶 API 的临时空间</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f808787aaed58ce7aaf48"><li>部分高阶 API 需要额外临时空间。例如 Sinh 接口可能需要 <code class="notion-inline-code">sharedTmpBuffer</code> 保存中间结果。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8031a991f5f7fa57a564"><li>接口一般提供两种使用方式：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8031a991f5f7fa57a564"><li>开发者显式传入临时空间。</li><li>使用无需显式临时空间参数的重载，由接口内部处理。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f802d899df544885b7943"><li>为了更好控制片上内存，Host 可以先计算高阶 API 所需临时空间的最小值和最大值，再把选择结果作为 Tiling 参数下发。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d28e12e259f045c93d"><li>概念流程：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d28e12e259f045c93d"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80e0a27bfa16eacc692f"><li>在允许范围内增大临时空间，有时可以<span class="notion-red"><b>带来更好的计算性能</b></span>，但也会<span class="notion-red"><b>占用更多片上内存</b></span>，因此需要在性能与内存之间权衡。</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3bae64bde40f802494fcee625977b1af" data-id="3bae64bde40f802494fcee625977b1af"><span><div id="3bae64bde40f802494fcee625977b1af" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f802494fcee625977b1af" title="5-算子的多种调用方式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5-算子的多种调用方式</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f8090805ed0851f87ee6d" data-id="3bae64bde40f8090805ed0851f87ee6d"><span><div id="3bae64bde40f8090805ed0851f87ee6d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8090805ed0851f87ee6d" title="5-1 算子调用概述"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5-1 算子调用概述</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f807383adc687a011631f" data-id="3bae64bde40f807383adc687a011631f"><span><div id="3bae64bde40f807383adc687a011631f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f807383adc687a011631f" title="两类工程对应两类调用体系"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">两类工程对应两类调用体系</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8013b1e8c8bf4a8be3bc"><li>不同开发方式支持的调用路径不同。</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8013b1e8c8bf4a8be3bc"><li><span class="notion-red"><b>Kernel 直调工程</b></span>：重点是直接调用核函数，适合开发和快速验证。</li><li><span class="notion-red"><b>自定义算子工程</b></span>：完成正式编译部署后，可以通过 AscendCL、模型执行或 PyTorch Adapter 等方式调用。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80278b9ad8d92c8162d6" data-id="3bae64bde40f80278b9ad8d92c8162d6"><span><div id="3bae64bde40f80278b9ad8d92c8162d6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80278b9ad8d92c8162d6" title="常见调用方式对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">常见调用方式对比</span></span></h4><table class="notion-simple-table notion-block-3bae64bde40f80198d20c7adf831d15f"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f805eaa0cc605c4de3b40"><td class="" style="width:141.4px"><div class="notion-simple-table-cell">工程</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">调用方式</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">运行硬件</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">典型用途</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">常见调试手段</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8064aab9e835caba2e0d"><td class="" style="width:141.4px"><div class="notion-simple-table-cell">Kernel 直调</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell"><code class="notion-inline-code">ICPU_RUN_KF</code></div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">CPU</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">CPU 仿真调试</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell"><code class="notion-inline-code">gdb</code>、<code class="notion-inline-code">printf</code>、<code class="notion-inline-code">std::cout</code></div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8062832ede49d53a4d82"><td class="" style="width:141.4px"><div class="notion-simple-table-cell">Kernel 直调</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell"><code class="notion-inline-code">&lt;&lt;&lt;...&gt;&gt;&gt;</code> 核函数调用</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">NPU</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">快速 NPU 验证</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell"><code class="notion-inline-code">printf</code>、DumpTensor</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80519ac2dde6ebacfe05"><td class="" style="width:141.4px"><div class="notion-simple-table-cell">Kernel 直调</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">Runtime Kernel Launch</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">NPU</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">通过运行时拉起 Kernel</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell"><code class="notion-inline-code">printf</code>、DumpTensor</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80cbaef2d244fe4157b3"><td class="" style="width:141.4px"><div class="notion-simple-table-cell">自定义算子工程</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">单算子 API（aclnn）</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">NPU</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">应用直接调用单算子</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell"><code class="notion-inline-code">printf</code>、DumpTensor</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8085bc07e477edd6635b"><td class="" style="width:141.4px"><div class="notion-simple-table-cell">自定义算子工程</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell"><code class="notion-inline-code">aclopExecuteV2</code></div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">NPU</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">单算子模型执行</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell"><code class="notion-inline-code">printf</code>、DumpTensor</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80ae91f7c23edc698c68"><td class="" style="width:141.4px"><div class="notion-simple-table-cell">自定义算子工程</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">PyTorch Adapter / op-plugin</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">NPU</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">PyTorch 框架调用</div></td><td class="" style="width:141.4px"><div class="notion-simple-table-cell">PyTorch 测试 + NPU 调试</div></td></tr></tbody></table><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a1a055cd837376c526"><li>推荐开发顺序：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a1a055cd837376c526"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f80aeb263f89077c051dc" style="list-style-type:decimal"><li>先在 CPU 侧验证算法和基本逻辑。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f800fabc0f5d1c7673eab" style="list-style-type:decimal"><li>再用 Kernel 直调在 NPU 上验证。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f8092a2c9d86ede73db38" style="list-style-type:decimal"><li>最后切换到正式工程和框架调用。</li></ol></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f8036b362d679a085c5d0" data-id="3bae64bde40f8036b362d679a085c5d0"><span><div id="3bae64bde40f8036b362d679a085c5d0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8036b362d679a085c5d0" title="5-2 Kernel 直调"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5-2 Kernel 直调</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8011b78ada7180a90174" data-id="3bae64bde40f8011b78ada7180a90174"><span><div id="3bae64bde40f8011b78ada7180a90174" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8011b78ada7180a90174" title="CPU 侧运行"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">CPU 侧运行</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8006a66ee575aef18b7f"><li>CPU 仿真模式的基本流程：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8006a66ee575aef18b7f"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f80c39f10cbb814623b7f" style="list-style-type:decimal"><li>为输入、输出申请共享内存。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f800c95aad2b328e5762a" style="list-style-type:decimal"><li>从文件读取输入数据。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f80709232d0b437f30451" style="list-style-type:decimal"><li>通过 CPU Kernel 调用宏执行核函数。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3bae64bde40f80c18ea6ee92c7ebd2f3" style="list-style-type:decimal"><li>把输出写入文件。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3bae64bde40f80fca7c0de429a34a927" style="list-style-type:decimal"><li>释放共享内存。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80fe896bda4c42de8376"><li>常见接口：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80fe896bda4c42de8376"><table class="notion-simple-table notion-block-3bae64bde40f80e6bc0ac7f916b9a603"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f80cdb89ae89c7a8a8d32"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">接口</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">用途</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8060bac4fbdec1952232"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">GmAlloc(size)</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">为 CPU 调测创建共享内存</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80b2be60d976ede6cbdb"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">ICPU_RUN_KF(...)</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">在 CPU 仿真环境调用 Kernel</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f808d8240e00821f36d34"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">GmFree(ptr)</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">释放共享内存</div></td></tr></tbody></table></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f803abebae0179052038a" data-id="3bae64bde40f803abebae0179052038a"><span><div id="3bae64bde40f803abebae0179052038a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f803abebae0179052038a" title="NPU 侧运行"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">NPU 侧运行</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80da93becef84782cf32"><li>NPU 模式通常需要：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80da93becef84782cf32"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f80878579eabe15e02694" style="list-style-type:decimal"><li>初始化 AscendCL。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f8016831cd5e5cdf1bf66" style="list-style-type:decimal"><li>设置 Device。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f80beb87df96f1ab6ba64" style="list-style-type:decimal"><li>创建 Context / Stream。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3bae64bde40f801dbadfce602a7e9541" style="list-style-type:decimal"><li>申请 Host / Device 内存。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3bae64bde40f80f1b434d55ca54aa4e8" style="list-style-type:decimal"><li>把输入从 Host 拷到 Device。</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3bae64bde40f8089babdd87b9f724dfa" style="list-style-type:decimal"><li>拉起 Kernel。</li></ol><ol start="7" class="notion-list notion-list-numbered notion-block-3bae64bde40f80a2bd41e8259a57fa2d" style="list-style-type:decimal"><li>把输出从 Device 拷回 Host。</li></ol><ol start="8" class="notion-list notion-list-numbered notion-block-3bae64bde40f80ef9481fdcbd8ceee1d" style="list-style-type:decimal"><li>同步 Stream。</li></ol><ol start="9" class="notion-list notion-list-numbered notion-block-3bae64bde40f80189063ed9a92e016d4" style="list-style-type:decimal"><li>释放内存、Stream、Context、Device。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80478a81eb4d84b6d855"><li>因为 Kernel 调用通常是异步的，所以读取结果前要确保对应 Stream 已经同步完成。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80d6a146f0278d8135fd" data-id="3bae64bde40f80d6a146f0278d8135fd"><span><div id="3bae64bde40f80d6a146f0278d8135fd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80d6a146f0278d8135fd" title="输入数据生成"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">输入数据生成</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8085911dd93dc73bfb9d"><li><code class="notion-inline-code">gen_data.py</code> 通常负责：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8085911dd93dc73bfb9d"><li>用 NumPy 随机生成 <code class="notion-inline-code">input_x</code>、<code class="notion-inline-code">input_y</code>。</li><li>计算 <code class="notion-inline-code">golden = input_x + input_y</code>。</li><li>将输入与 Golden 结果写成 <code class="notion-inline-code">.bin</code> 文件。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8052a95ac01b8a8beb27"><li>这样 Host 测试程序只负责读取二进制数据并执行 Kernel。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80f393bff0c72a17cd41" data-id="3bae64bde40f80f393bff0c72a17cd41"><span><div id="3bae64bde40f80f393bff0c72a17cd41" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80f393bff0c72a17cd41" title="结果校验"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">结果校验</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8055affbd1c5b1d36491"><li><code class="notion-inline-code">verify_result.py</code> 读取：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8055affbd1c5b1d36491"><li>NPU/CPU Kernel 实际输出。</li><li>Golden 输出。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d8871deae22e945f9a"><li>再使用容差比较，判断结果是否通过。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8007ac26d735d50613b3" data-id="3bae64bde40f8007ac26d735d50613b3"><span><div id="3bae64bde40f8007ac26d735d50613b3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8007ac26d735d50613b3" title="Kernel 直调也可以使用 Tiling"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Kernel 直调也可以使用 Tiling</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f809c8753e82ff4bbeabe"><li>Kernel 直调并不意味着不能使用 Tiling。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d49fdbcb35693da5f4"><li>与标准工程相比，Kernel 直调更自由：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d49fdbcb35693da5f4"><li>Tiling 数据可以自己定义结构体。</li><li>不一定要使用标准 Host 侧 Tiling 注册流程。</li><li>调用 Kernel 前直接构造 Tiling 数据并传入即可。</li><li>Kernel 参数也不一定必须写成统一的 <code class="notion-inline-code">GM_ADDR tiling</code> 形式，只要调用端和 Kernel 端保持一致。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8006993bf92e450c814c"><li>因此它很适合<span class="notion-red"><b>先验证</b></span>复杂切分逻辑，<span class="notion-red"><b>再迁移</b></span>到标准工程。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f800ab07ff9ad98ad082c" data-id="3bae64bde40f800ab07ff9ad98ad082c"><span><div id="3bae64bde40f800ab07ff9ad98ad082c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f800ab07ff9ad98ad082c" title="5-3 通过 Ascend CL 调用算子"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5-3 通过 Ascend CL 调用算子</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f802abc26fad56f922a2f" data-id="3bae64bde40f802abc26fad56f922a2f"><span><div id="3bae64bde40f802abc26fad56f922a2f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f802abc26fad56f922a2f" title="AscendCL 单算子调用的两种方式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">AscendCL 单算子调用的两种方式</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80d3ab5beaeee6d3d97c"><li>完成标准自定义算子开发和部署后，可以使用 AscendCL 执行单算子。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f804db6f6e364b670e733"><li>主要有两种方式：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f804db6f6e364b670e733"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f803bbba0ece1041df9d2" style="list-style-type:decimal"><li><span class="notion-red"><b>单算子 API 执行（aclnn）</b></span>：直接调用生成的单算子 API。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f80048a69c414c2e243f4" style="list-style-type:decimal"><li><span class="notion-red"><b>单算子模型执行</b></span>：先把算子描述编译成离线模型，再用 <code class="notion-inline-code">aclopExecuteV2</code> 等接口执行。</li></ol></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80f5b7c9ecb563cb7d4a" data-id="3bae64bde40f80f5b7c9ecb563cb7d4a"><span><div id="3bae64bde40f80f5b7c9ecb563cb7d4a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80f5b7c9ecb563cb7d4a" title="两种方式的工程要求"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">两种方式的工程要求</span></span></h4><table class="notion-simple-table notion-block-3bae64bde40f805789e2db8cffeff16d"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f8022a5f0c08bf1e37cc3"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">项目</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">单算子 API 执行</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">单算子模型执行</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8036aa6ce210063d12a8"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">Kernel 实现</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">必须</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">必须</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80ffbbb1ef9ba8485cc1"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">原型注册</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">必须</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">必须</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f804b890ff03dba85efe7"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">Shape 推导</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">可不依赖</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">必须</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80909b06dfa3d94dc6bb"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">Tiling</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">必须</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">必须</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f805694f7d83ba38fa71d"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">算子源码编译</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">不作为主要路径</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">开启</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8030956cc25a382d9af4"><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">算子二进制编译</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">开启</div></td><td class="" style="width:235.66666666666666px"><div class="notion-simple-table-cell">不作为主要路径</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80ef8653c266e385556c" data-id="3bae64bde40f80ef8653c266e385556c"><span><div id="3bae64bde40f80ef8653c266e385556c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80ef8653c266e385556c" title="源码编译与二进制编译"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">源码编译与二进制编译</span></span></h4><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3bae64bde40f804988cbf5e0cf351db2" data-id="3bae64bde40f804988cbf5e0cf351db2"><span><div id="3bae64bde40f804988cbf5e0cf351db2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f804988cbf5e0cf351db2" title="二进制编译"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">二进制编译</span></span></h5><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80f8942ad43d73d18b7e"><li>会对 Kernel 实现进行编译，生成：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80f8942ad43d73d18b7e"><li>算子描述信息。</li><li>相关 JSON。</li><li>算子二进制文件。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8059a03adc75ce792001"><li>适合直接调用已经编译好的单算子二进制。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3bae64bde40f807c903df03e73997323" data-id="3bae64bde40f807c903df03e73997323"><span><div id="3bae64bde40f807c903df03e73997323" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f807c903df03e73997323" title="源码编译"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">源码编译</span></span></h5><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80df81e6d247d7465222"><li>保留 Kernel 源码，不预先把 Kernel 固化为最终二进制。模型转换阶段可由 ATC 等工具结合目标环境进行编译。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80c58c40e998dca19c69"><li>适合算子随模型一起转换、编译和加载的场景。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f807cbf58ce72ff95a185" data-id="3bae64bde40f807cbf58ce72ff95a185"><span><div id="3bae64bde40f807cbf58ce72ff95a185" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f807cbf58ce72ff95a185" title="单算子 API（aclnn）调用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">单算子 API（aclnn）调用</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b9b606c33fd75f9cbb"><li>自定义算子二进制编译部署后，会生成相应的单算子 API。API 常采用两段式：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b9b606c33fd75f9cbb"></ul></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3bae64bde40f80189c1aee40e3486ed7" data-id="3bae64bde40f80189c1aee40e3486ed7"><span><div id="3bae64bde40f80189c1aee40e3486ed7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80189c1aee40e3486ed7" title="第一阶段：GetWorkspaceSize"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第一阶段：GetWorkspaceSize</span></span></h5><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8048b494c3daf72441e1"><li>作用：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8048b494c3daf72441e1"><li>校验参数。</li><li>计算本次执行需要的 Workspace 大小。</li><li>创建/返回执行器 <code class="notion-inline-code">executor</code>。</li></ul></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3bae64bde40f80a293a7f5857b143166" data-id="3bae64bde40f80a293a7f5857b143166"><span><div id="3bae64bde40f80a293a7f5857b143166" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80a293a7f5857b143166" title="第二阶段：执行接口"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第二阶段：执行接口</span></span></h5><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8055ae3cc818f2a24b55"><li>作用：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8055ae3cc818f2a24b55"><li>根据 <code class="notion-inline-code">workspaceSize</code> 准备 Device Workspace。</li><li>传入 <code class="notion-inline-code">executor</code> 和 Stream。</li><li>异步执行算子。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a2aaa2f14e9a419c4a"><li>典型调用顺序：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a2aaa2f14e9a419c4a"></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f800291cac86d97c5b4dd" data-id="3bae64bde40f800291cac86d97c5b4dd"><span><div id="3bae64bde40f800291cac86d97c5b4dd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f800291cac86d97c5b4dd" title="单算子 API 调用程序编译"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">单算子 API 调用程序编译</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80728155eb3f22c516f8"><li>调用程序需要在 CMake 中配置：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80728155eb3f22c516f8"><li>自定义算子包的 include 目录。</li><li>自定义算子包的 lib 目录。</li><li>AscendCL 相关 include/lib。</li><li>自定义单算子 API 库。</li><li>运行时依赖库。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80e6b42ac60fb1a3ef9a"><li>最终生成调用程序后，即可直接调用安装好的自定义算子。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f805c90bdd0153532ac0b" data-id="3bae64bde40f805c90bdd0153532ac0b"><span><div id="3bae64bde40f805c90bdd0153532ac0b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f805c90bdd0153532ac0b" title="单算子模型执行"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">单算子模型执行</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f800685eff34363709c52"><li>另一种方式是把算子先转成离线模型。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8068b017f702a2901537"><li>流程：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8068b017f702a2901537"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b0b397f9a14eb615b5"><li>关键接口包括：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b0b397f9a14eb615b5"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8068a535d5df1e9cac45"><li>JSON 描述需要明确：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8068a535d5df1e9cac45"><li>算子类型。</li><li>输入名称。</li><li>输入 Shape。</li><li>输入 dtype。</li><li>输入 Format。</li><li>输出描述。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8024b23ff982011fc0fe"><li>ATC 的核心参数包括：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8024b23ff982011fc0fe"><li><code class="notion-inline-code">-singleop</code>：单算子描述 JSON。</li><li><code class="notion-inline-code">-output</code>：输出模型目录/前缀。</li><li><code class="notion-inline-code">-soc_version</code>：目标 AI 处理器型号。</li></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f809e9e55c85d6c132ef3" data-id="3bae64bde40f809e9e55c85d6c132ef3"><span><div id="3bae64bde40f809e9e55c85d6c132ef3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f809e9e55c85d6c132ef3" title="5-4 通过 PyTorch 调用算子"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5-4 通过 PyTorch 调用算子</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80978cdaf827c564f976" data-id="3bae64bde40f80978cdaf827c564f976"><span><div id="3bae64bde40f80978cdaf827c564f976" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80978cdaf827c564f976" title="PyTorch 适配的总体思路"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">PyTorch 适配的总体思路</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80349527d6f145ed49e9"><li>PyTorch 在训练和推理中会调用大量算子。Ascend Extension for PyTorch 的 <code class="notion-inline-code">op-plugin</code> 提供算子适配机制，<span class="notion-red"><b>把 PyTorch 算子映射到昇腾侧实现</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f807ea36bfc58bf234f25"><li>适配主要包含两部分：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f807ea36bfc58bf234f25"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f80f794f7d806c04af4b0" style="list-style-type:decimal"><li><span class="notion-red"><b>算子注册分发</b></span>：在 YAML 中描述算子定义和后端映射关系。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f80f393e8c95ac2c12b75" style="list-style-type:decimal"><li><span class="notion-red"><b>适配插件实现</b></span>：编写 C++ 适配代码，在 PyTorch 接口与昇腾单算子 API 之间做参数转换和调用。</li></ol></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8082a742c29436b023b3" data-id="3bae64bde40f8082a742c29436b023b3"><span><div id="3bae64bde40f8082a742c29436b023b3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8082a742c29436b023b3" title="工程准备"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">工程准备</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80308ad0c353df2c6dd7"><li>示例工程通常包含：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80308ad0c353df2c6dd7"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8085b3cbed6cc5ca3288"><li>C++ 适配层主要完成：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8085b3cbed6cc5ca3288"><li>接收 PyTorch Tensor。</li><li>创建输出 Tensor。</li><li>调用昇腾侧单算子 API。</li><li>返回 PyTorch Tensor。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80e9be6cf9e4ef5f1cc3" data-id="3bae64bde40f80e9be6cf9e4ef5f1cc3"><span><div id="3bae64bde40f80e9be6cf9e4ef5f1cc3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80e9be6cf9e4ef5f1cc3" title="算子注册分发配置"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">算子注册分发配置</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f802ebbfcc02ae61183ec"><li><code class="notion-inline-code">op_plugin_functions.yaml</code> 用来描述：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f802ebbfcc02ae61183ec"><li>算子是否属于官方算子或自定义算子。</li><li><code class="notion-inline-code">func</code>：算子的函数签名，包括名称、输入和返回值。</li><li><code class="notion-inline-code">impl_ns</code>：指定后端实现所对应的命名空间/调用路径。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80f4b2eecc37f8022002"><li>对于自定义算子，需要先在该配置中加入函数定义，再为其提供实际 C++ 实现。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8082a944cb38b2dcdd80" data-id="3bae64bde40f8082a944cb38b2dcdd80"><span><div id="3bae64bde40f8082a944cb38b2dcdd80" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8082a944cb38b2dcdd80" title="op-plugin 编译部署"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">op-plugin 编译部署</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80fd98b6f280e24d5d4f"><li>基本过程：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80fd98b6f280e24d5d4f"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f80e3a012f223029accd1" style="list-style-type:decimal"><li>获取 <code class="notion-inline-code">op-plugin</code> 源码。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f80b794c8ddd93d5b2516" style="list-style-type:decimal"><li>合入自定义算子的 C++ 实现和 YAML 配置。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f8084867ef83aad3126e7" style="list-style-type:decimal"><li>重新编译 <code class="notion-inline-code">op-plugin</code>。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3bae64bde40f8012ac3af0629b29cfa2" style="list-style-type:decimal"><li>安装生成的 Python wheel 包。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3bae64bde40f80beb546da43451bb53c" style="list-style-type:decimal"><li>在 PyTorch 中调用并验证。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a088f3e6929d94702c"><li>示例安装流程可概括为：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a088f3e6929d94702c"></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80bdb122dbb0ec391db8" data-id="3bae64bde40f80bdb122dbb0ec391db8"><span><div id="3bae64bde40f80bdb122dbb0ec391db8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80bdb122dbb0ec391db8" title="PyTorch 调用测试"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">PyTorch 调用测试</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f804b942bf6c5f80832bb"><li>测试脚本通常：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f804b942bf6c5f80832bb"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f80449467c443c895dbb0" style="list-style-type:decimal"><li>创建 CPU/PyTorch 参考输入。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f804f8b74f08ab41c99ce" style="list-style-type:decimal"><li>把输入移动到 NPU。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f80df8ba0f12cead956ab" style="list-style-type:decimal"><li>调用注册后的自定义算子，例如：</li><ol class="notion-list notion-list-numbered notion-block-3bae64bde40f80df8ba0f12cead956ab" style="list-style-type:lower-alpha"></ol></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3bae64bde40f804ea906e2a955511c49" style="list-style-type:decimal"><li>把结果转回 CPU。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3bae64bde40f8091af14ea0dde4594d3" style="list-style-type:decimal"><li>与参考结果比较。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f802fa5e2d91acf42e316"><li>完整链路因此是：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f802fa5e2d91acf42e316"></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3bae64bde40f801f9589df0c42769d75" data-id="3bae64bde40f801f9589df0c42769d75"><span><div id="3bae64bde40f801f9589df0c42769d75" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f801f9589df0c42769d75" title="6-非对齐尾块处理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6-非对齐尾块处理</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80dd96d5df10c8737a63" data-id="3bae64bde40f80dd96d5df10c8737a63"><span><div id="3bae64bde40f80dd96d5df10c8737a63" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80dd96d5df10c8737a63" title="问题背景"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">问题背景</span></span></h3><ul class="notion-list notion-list-disc notion-block-3bae64bde40f803db4f3c1501b701269"><li>前面的 Add 示例使用 <code class="notion-inline-code">(8, 2048)</code> 的 <code class="notion-inline-code">half</code> Tensor，可以比较自然地按多个 AI Core 平均切分，且每块数据容易满足 32 Byte 对齐。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8008bf46dc17b3ef5a36"><li>如果输入变成：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8008bf46dc17b3ef5a36"><li>情况就不同了。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80008873ed817716adfb"><li><code class="notion-inline-code">half</code> 占 2 Byte，因此真实输入数据大小为：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80008873ed817716adfb"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f803baf92f74d7dc22e09"><li>Ascend C 的很多数据搬运和向量计算要求按 <b>32 Byte block</b> 组织数据：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f803baf92f74d7dc22e09"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80f5a454e085bd309b9c"><li>1320 Byte 不是 32 Byte 的整数倍，需要向上对齐：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80f5a454e085bd309b9c"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8016bd16f1466c836733"><li>即从元素角度看，相当于：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8016bd16f1466c836733"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80198a59e504ca34e4d6"><li>其中：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80198a59e504ca34e4d6"><li>660 个是真实数据。</li><li>12 个只是对齐后的尾部空间，不应该作为有效输出参与最终语义。</li></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f800b8106c37df2522f68" data-id="3bae64bde40f800b8106c37df2522f68"><span><div id="3bae64bde40f800b8106c37df2522f68" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f800b8106c37df2522f68" title="多核切分：不能再简单平均"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">多核切分：不能再简单平均</span></span></h3><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8081acd6e67859a424cc"><li>42 个 block 要分配给 4 个 AI Core：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8081acd6e67859a424cc"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8032b231f441f3d70ee0"><li>因此可以采用：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8032b231f441f3d70ee0"><li>2 个“大核”：每核处理 11 block。</li><li>2 个“小核”：每核处理 10 block。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80ceaa17f0f4668e7faf"><li>即：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80ceaa17f0f4668e7faf"></ul></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3bae64bde40f808aa09cdf5105c1fd53"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3A892ddc36-c1d1-4c40-8bf7-c02fbfa48112%3A%E9%9D%9E%E5%AF%B9%E9%BD%90%E6%95%B0%E6%8D%AE%E7%9A%84%E5%A4%9A%E6%A0%B8%E5%88%87%E5%88%86.png?table=block&amp;id=3bae64bd-e40f-808a-a09c-df5105c1fd53&amp;t=3bae64bd-e40f-808a-a09c-df5105c1fd53" alt="非对齐数据的多核切分" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">非对齐数据的多核切分</figcaption></div></figure><ul class="notion-list notion-list-disc notion-block-3bae64bde40f802195e5ea754be39341"><li>这意味着 Kernel 中不能再假定：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f802195e5ea754be39341"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80edaff6e205bac44990"><li>而要根据 <code class="notion-inline-code">block_idx</code> 判断当前属于大核还是小核，从 TilingData 中读取不同的数据长度。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80cbae9efe54e5362dec" data-id="3bae64bde40f80cbae9efe54e5362dec"><span><div id="3bae64bde40f80cbae9efe54e5362dec" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80cbae9efe54e5362dec" title="单核内部还要受 UB 容量限制"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">单核内部还要受 UB 容量限制</span></span></h3><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80c69551d3ba7ed3e88d"><li>即使已经把数据分到多个核，每个核一次能处理多少数据还受到 Local Memory / UB 大小限制。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8000a71dce202cd6ba05"><li>因此需要再次把单核数据切成多个 Tile：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8000a71dce202cd6ba05"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80ecb2e2eb6a8dddb3d9"><li>大多数 Tile 可以使用相同长度，最后一个 Tile 可能是尾块。</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3bae64bde40f8063b758fb66b482f1ab"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3Af4894724-3a8b-4ed9-bd13-7a5c9bfc3ad1%3A%E5%8D%95%E6%A0%B8%E5%86%85%E6%8C%89_UB_%E7%BB%A7%E7%BB%AD%E5%88%87%E5%88%86.png?table=block&amp;id=3bae64bd-e40f-8063-b758-fb66b482f1ab&amp;t=3bae64bd-e40f-8063-b758-fb66b482f1ab" alt="单核内按 UB 继续切分" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">单核内按 UB 继续切分</figcaption></div></figure><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f8008aa5edae6c51517fd" data-id="3bae64bde40f8008aa5edae6c51517fd"><span><div id="3bae64bde40f8008aa5edae6c51517fd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8008aa5edae6c51517fd" title="复杂 TilingData 的设计"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">复杂 TilingData 的设计</span></span></h3><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80a99ef8fabea769eb0e"><li>为了让 Kernel 正确处理“大核/小核 + 普通 Tile/尾 Tile”，Host 侧需要下发更多信息。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8021b77cd266a4a74844"><li>典型字段包括：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8021b77cd266a4a74844"><table class="notion-simple-table notion-block-3bae64bde40f80d182bff5a20da9cc3d"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3bae64bde40f80fc895ad09ae94d3b6c"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">字段</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">含义</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8092a2d1fa68b5245bb2"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">smallCoreDataNum</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">小核总处理数据量</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f808faebdc8c6cd4b3e31"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">bigCoreDataNum</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">大核总处理数据量</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80e7bf57c5c220809226"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">finalSmallTileNum</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">小核最后一个 Tile 的有效数据量/相关切分参数</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80f68ed2fc85b96159f6"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">finalBigTileNum</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">大核最后一个 Tile 的有效数据量/相关切分参数</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80c4ae5ce8b5d96cf6ae"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">tileDataNum</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">普通 Tile 的数据量</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f80199850e2fe7aae66ac"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">smallTailDataNum</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">小核尾 Tile 的有效数据量</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8062986ce995a19fe92b"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">bigTailDataNum</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">大核尾 Tile 的有效数据量</div></td></tr><tr class="notion-simple-table-row notion-block-3bae64bde40f8038b06ec39df388acda"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">tailBlockNum</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">尾部对齐处理所需 block 数等尾块信息</div></td></tr></tbody></table></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80979b5accb840119fb3"><li>具体字段可以根据实现调整，核心目标是让 Kernel 能回答三个问题：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80979b5accb840119fb3"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f806da232cbaee17a1c11" style="list-style-type:decimal"><li><span class="notion-red"><b>我这个核要处理多少数据？</b></span></li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f801ab547f017b4698c01" style="list-style-type:decimal"><li><span class="notion-red"><b>我要循环多少个普通 Tile？</b></span></li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f8093a9e7e9ef7000aa3e" style="list-style-type:decimal"><li><span class="notion-red"><b>最后一个 Tile 到底有多少有效元素？</b></span></li></ol></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80c69bdcf46706dcfd5d" data-id="3bae64bde40f80c69bdcf46706dcfd5d"><span><div id="3bae64bde40f80c69bdcf46706dcfd5d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80c69bdcf46706dcfd5d" title="Host 侧复杂 Tiling 的计算思路"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Host 侧复杂 Tiling 的计算思路</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f807a8fc7c772e437b58f" data-id="3bae64bde40f807a8fc7c772e437b58f"><span><div id="3bae64bde40f807a8fc7c772e437b58f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f807a8fc7c772e437b58f" title="1. 获取 Shape 和 dtype"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 获取 Shape 和 dtype</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80c1b183e45e970afcea"><li>Host 从 <code class="notion-inline-code">TilingContext</code> 获取输入 Shape 和数据类型，计算：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80c1b183e45e970afcea"></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8045a545ee9475f05f28" data-id="3bae64bde40f8045a545ee9475f05f28"><span><div id="3bae64bde40f8045a545ee9475f05f28" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8045a545ee9475f05f28" title="2. 按 32 Byte 对齐"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 按 32 Byte 对齐</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8024b9d1e4264bcb4071" data-id="3bae64bde40f8024b9d1e4264bcb4071"><span><div id="3bae64bde40f8024b9d1e4264bcb4071" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8024b9d1e4264bcb4071" title="3. 根据核数分配 block"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 根据核数分配 block</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80daa6a2f02aee040dee"><li>假设使用 <code class="notion-inline-code">coreNum</code> 个核：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80daa6a2f02aee040dee"><li>前 <code class="notion-inline-code">remainder</code> 个核多拿 1 block。</li><li>其余核拿 <code class="notion-inline-code">baseBlocks</code> 个 block。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8059bc02de4708f600c8"><li>由此得到大核和小核的处理长度。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80018439dab692b159a7" data-id="3bae64bde40f80018439dab692b159a7"><span><div id="3bae64bde40f80018439dab692b159a7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80018439dab692b159a7" title="4. 根据 UB 大小计算 Tile"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. 根据 UB 大小计算 Tile</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8058a10dc9bb7531775d"><li>再根据可用 UB 大小、双缓冲数量和 dtype 计算普通 Tile 能放多少元素。</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8058a10dc9bb7531775d"></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8067ba6bf7575a3c45f1" data-id="3bae64bde40f8067ba6bf7575a3c45f1"><span><div id="3bae64bde40f8067ba6bf7575a3c45f1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8067ba6bf7575a3c45f1" title="5. 计算尾 Tile"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5. 计算尾 Tile</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b7bb7cf1e845e26d95"><li>分别计算大核和小核：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b7bb7cf1e845e26d95"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8054aa17c91e76c0feb9"><li>这些值全部写入 TilingData 下发给 Kernel。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80f9a34cd081ad0a7f92" data-id="3bae64bde40f80f9a34cd081ad0a7f92"><span><div id="3bae64bde40f80f9a34cd081ad0a7f92" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80f9a34cd081ad0a7f92" title="Kernel 侧处理逻辑"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Kernel 侧处理逻辑</span></span></h3><ul class="notion-list notion-list-disc notion-block-3bae64bde40f808aa46dfbfdc57e5376"><li>Kernel 的 <code class="notion-inline-code">Init()</code> 不再使用一套固定常量，而是：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f808aa46dfbfdc57e5376"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f80e49f4dc5062e6c7e46" style="list-style-type:decimal"><li>读取 TilingData。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f8055a00dea2293b31b97" style="list-style-type:decimal"><li>获取 <code class="notion-inline-code">block_idx</code>。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3bae64bde40f803495a9f8eb74a0171e" style="list-style-type:decimal"><li>判断当前是大核还是小核。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3bae64bde40f8063ab6edc9740554f4f" style="list-style-type:decimal"><li>计算当前核的 GlobalTensor 起始偏移。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3bae64bde40f80d88e19fd93a58d568b" style="list-style-type:decimal"><li>确定本核普通 Tile 数与尾 Tile 长度。</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3bae64bde40f809d99ecf13d73a03dea" style="list-style-type:decimal"><li>初始化 Queue/Buffer。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8036b917d33620351de0"><li>伪代码：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8036b917d33620351de0"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8001a5b8dece66d4f6e1"><li><code class="notion-inline-code">Process()</code> 中普通 Tile 可以复用原来的 CopyIn → Compute → CopyOut 逻辑；最后一个 Tail Tile 则需要使用实际有效元素数处理。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80b88610f75337b33766" data-id="3bae64bde40f80b88610f75337b33766"><span><div id="3bae64bde40f80b88610f75337b33766" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80b88610f75337b33766" title="为什么要区分“搬运长度”和“有效计算长度”"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">为什么要区分“搬运长度”和“有效计算长度”</span></span></h3><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80809561daf853c8a40f"><li>尾块处理最容易混淆的地方是：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80809561daf853c8a40f"><li><span class="notion-red"><b>搬运</b></span>可能需要满足 32 Byte 对齐。</li><li><span class="notion-red"><b>真实数学计算</b></span>只应该覆盖有效元素。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b38835c72a2ef46746"><li>例如真实只剩 4 个 <code class="notion-inline-code">half</code>：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80b38835c72a2ef46746"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f801da6f6c1baef4dadda"><li>为了满足搬运要求，可能仍然需要按一个 32 Byte block 处理内存，但计算时应通过 <code class="notion-inline-code">count</code>、Mask 或额外逻辑确保只有真实元素参与最终语义。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f800a9eb7f5411d6ee079"><li><span class="notion-red"><b>核心原则</b></span>：对齐是硬件访问要求，不等于对齐补出来的数据也属于 Tensor 的有效数据。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f80a3a905f0efc073c89e" data-id="3bae64bde40f80a3a905f0efc073c89e"><span><div id="3bae64bde40f80a3a905f0efc073c89e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80a3a905f0efc073c89e" title="多数据类型算子实现"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">多数据类型算子实现</span></span></h3><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80fabbb9cf75a103f97a"><li>复杂 Shape 处理完后，还需要考虑另一类通用性问题：<span class="notion-red"><b>同一个算子支持多种 dtype</b></span>。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f80dd8697c2689b71bc21" data-id="3bae64bde40f80dd8697c2689b71bc21"><span><div id="3bae64bde40f80dd8697c2689b71bc21" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f80dd8697c2689b71bc21" title="Host 侧注册多种 dtype"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Host 侧注册多种 dtype</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80789dd1f5942973b0b2"><li>算子描述 JSON 和 Host 侧原型注册需要声明支持的数据类型。例如同一输入可能支持：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80789dd1f5942973b0b2"><li><code class="notion-inline-code">half</code></li><li><code class="notion-inline-code">float</code></li><li><code class="notion-inline-code">int32</code></li><li><code class="notion-inline-code">int8</code></li></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80bcb067c1338827648f"><li>输入、输出的数据类型约束要保持一致或按算子语义明确转换关系。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8053ad69ccbafb39e938" data-id="3bae64bde40f8053ad69ccbafb39e938"><span><div id="3bae64bde40f8053ad69ccbafb39e938" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8053ad69ccbafb39e938" title="Kernel 侧模板化"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Kernel 侧模板化</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80bbb6d0f723caca1401"><li>Kernel 可通过模板类型统一实现：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80bbb6d0f723caca1401"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80bab19aedcb775ece6d"><li>这样可以复用大部分搬运、切分和流水代码。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3bae64bde40f8013a47cf6fc07977d46" data-id="3bae64bde40f8013a47cf6fc07977d46"><span><div id="3bae64bde40f8013a47cf6fc07977d46" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f8013a47cf6fc07977d46" title="计算 API 不支持当前 dtype 时怎么办"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">计算 API 不支持当前 dtype 时怎么办</span></span></h4><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8081af96d78c8a0e5eb3"><li>即使 Host 注册了某个 dtype，也不代表所使用的 Vector API 一定直接支持它。</li></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8023a20cced06f511155"><li>例如某个 <code class="notion-inline-code">Add</code> 基础 API 不直接支持当前 <code class="notion-inline-code">int8</code> 输入时，可以采用：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8023a20cced06f511155"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80f3bce1c20aa0bbf7e9"><li>实现时可以使用 <code class="notion-inline-code">if constexpr</code> 针对特定模板类型走专用分支：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f80f3bce1c20aa0bbf7e9"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8061b276f84213e5d5b6"><li>因此，“算子支持某 dtype”需要同时满足两层条件：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8061b276f84213e5d5b6"><ol start="1" class="notion-list notion-list-numbered notion-block-3bae64bde40f80ccad2edf4d16992145" style="list-style-type:decimal"><li><span class="notion-red"><b>Host 原型允许该 dtype。</b></span></li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3bae64bde40f806baba9e90b9ebf7112" style="list-style-type:decimal"><li><span class="notion-red"><b>Kernel 内部存在可执行的计算路径。</b></span></li></ol></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3bae64bde40f809c9a23f17421daaf28" data-id="3bae64bde40f809c9a23f17421daaf28"><span><div id="3bae64bde40f809c9a23f17421daaf28" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3bae64bde40f809c9a23f17421daaf28" title="非对齐尾块处理的完整思路"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">非对齐尾块处理的完整思路</span></span></h3><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8049b360d488801d6a35"><li>最终可以把这一章归纳为一条通用切分链路：</li><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8049b360d488801d6a35"></ul></ul><ul class="notion-list notion-list-disc notion-block-3bae64bde40f8057a53aedf773047d11"><li>这套方法不仅适用于 <code class="notion-inline-code">(1, 660)</code> 的 Add，也适用于更一般的动态 Shape、非对齐输入和多数据类型 Vector 算子。</li></ul></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ascend C算子开发（入门）笔记]]></title>
            <link>http://blog.zzhow.com/article/AscendC-Introduction</link>
            <guid>http://blog.zzhow.com/article/AscendC-Introduction</guid>
            <pubDate>Mon, 10 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Ascend C算子开发（入门）笔记，包含 算子基本概念；Tensor、Shape、Format 与 Axis；算子运行演示；算子开发的问题与挑战；CANN 与 Ascend C；昇腾 AI 处理器架构；Ascend C 的特点；Host 与 Device；核函数；Hello World 算子实现；完整核函数实现；算子开发环境部署概述；CPU 上部署开发环境；香橙派上部署开发及运行环境；华为云 ModelArts 上部署开发与运行环境]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-3b8e64bde40f8038ad1ffb6284ffc178"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-sync-block notion-block-3b8e64bde40f80178fc9fc9f2c35c975"><div class="notion-text notion-block-3b7e64bde40f8057983bd490f76aa485">@ZZHow(ZZHow1024)</div><div class="notion-text notion-block-3b7e64bde40f80c9b3d4cdc91ad04148">参考课程：</div><div class="notion-text notion-block-3b7e64bde40f809e88b1fc9cb66756cc"><b>【Ascend C算子开发（入门）】</b></div><div class="notion-text notion-block-3b8e64bde40f8049a3bcc1725ea868c3"><b>[</b><b><a class="notion-link" href="https://www.hiascend.com/developer/courses/detail/1691696509765107713" target="_blank" rel="noopener noreferrer">https://www.hiascend.com/developer/courses/detail/1691696509765107713</a></b><b>]</b></div><div class="notion-text notion-block-3b8e64bde40f80d68820f3668b9ad126"><b>【Ascend C系列教程（初级）】</b></div><div class="notion-text notion-block-3b8e64bde40f8081b6f9ce591df2195a"><b>[</b><b><a class="notion-link" href="https://www.bilibili.com/video/BV1QgigeYEoz" target="_blank" rel="noopener noreferrer">https://www.bilibili.com/video/BV1QgigeYEoz</a></b><b>]</b></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3b8e64bde40f80d5bf1ec75fe6994d45" data-id="3b8e64bde40f80d5bf1ec75fe6994d45"><span><div id="3b8e64bde40f80d5bf1ec75fe6994d45" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80d5bf1ec75fe6994d45" title="1-什么是算子"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1-什么是算子</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f80b5967fcd326576a4e0" data-id="3b8e64bde40f80b5967fcd326576a4e0"><span><div id="3b8e64bde40f80b5967fcd326576a4e0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80b5967fcd326576a4e0" title="1-1 算子基本概念"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1-1 算子基本概念</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80adaa81eaf01e2e14f3" data-id="3b8e64bde40f80adaa81eaf01e2e14f3"><span><div id="3b8e64bde40f80adaa81eaf01e2e14f3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80adaa81eaf01e2e14f3" title="人工智能的起点与基本层次"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">人工智能的起点与基本层次</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a695c2eccc2a00f258"><li>1956 年，美国达特茅斯人工智能研讨会召开，“人工智能（Artificial Intelligence）”概念由此正式进入研究视野。会议相关的代表人物包括约翰·麦卡锡（J. McCarthy）、马文·明斯基（M. L. Minsky）、克劳德·香农（C. E. Shannon）和 N. Rochester。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80d3867bf53d40d9cbda"><li><span class="notion-red"><b>人工智能</b></span>的目标，是让<span class="notion-red"><b>机器表现出类似人的智能行为</b></span>，可以完成感知、认知、决策和执行等活动。按能力层次可以理解为：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80d3867bf53d40d9cbda"><li><span class="notion-red"><b>计算智能</b></span>：能够进行计算，具备较强的存储能力和较快的计算能力。</li><li><span class="notion-red"><b>感知智能</b></span>：能够感知视觉、听觉、触觉等环境信息，例如“会听、会说”。</li><li><span class="notion-red"><b>认知智能</b></span>：能够理解、思考和决策。</li><li><span class="notion-red"><b>行动智能</b></span>：能够自主学习、自主决策，并根据决策执行动作。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f8071bdd2c4a3c1fc7bfd" data-id="3b8e64bde40f8071bdd2c4a3c1fc7bfd"><span><div id="3b8e64bde40f8071bdd2c4a3c1fc7bfd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8071bdd2c4a3c1fc7bfd" title="人工智能的三大流派"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">人工智能的三大流派</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80c28f2be09c86fda914"><li>人工智能研究的发展过程中形成了符号主义、连接主义和行动主义三类典型思路。</li></ul><table class="notion-simple-table notion-block-3b8e64bde40f804089c8c1131701e6ac"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3b8e64bde40f801a881fdcf5e1d567d0"><td class="" style="width:120px"><div class="notion-simple-table-cell">流派</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">核心思想</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">代表方向/特点</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80aeb9bcd571ae5c0216"><td class="" style="width:120px"><div class="notion-simple-table-cell">符号主义</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">用符号、知识和逻辑规则描述认知过程</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">逻辑推理、启发式搜索、专家系统、知识工程</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80ab96a4e34285f13cb1"><td class="" style="width:120px"><div class="notion-simple-table-cell">连接主义</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">用人工神经网络模拟神经系统的信息处理过程</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">BP 反向传播、卷积神经网络、循环神经网络、生成式神经网络等</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f802bbcf8eaae3997f95f"><td class="" style="width:120px"><div class="notion-simple-table-cell">行动主义</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">通过智能体的实际行为体现智能</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">机器人自主行动等场景</div></td></tr></tbody></table><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3b8e64bde40f80e18017c167dc0030ba" data-id="3b8e64bde40f80e18017c167dc0030ba"><span><div id="3b8e64bde40f80e18017c167dc0030ba" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80e18017c167dc0030ba" title="符号主义"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">符号主义</span></span></h5><div class="notion-text notion-block-3b8e64bde40f8055a4a7c0ad82a1bfc6">符号主义认为，人类认知和思维的基本单元是“符号”，基于符号的一系列运算构成认知过程。计算机可以通过符号运算模拟人的智能活动。</div><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f803f85d8d0ba466ef312"><li>优点：<span class="notion-red"><b>依赖知识推理，可解释性强</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8055b4e7fc9dd7c42114"><li>缺点：<span class="notion-red"><b>过度依赖专家知识和规则，不具备从数据中学习的能力，可扩展性较弱</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80588e26dae4a2a4dab2"><li>代表成果：逻辑理论家、启发式搜索、专家系统、知识工程等。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f802e99fff89866bf6b68"><li>典型案例：IBM Watson 自动问答系统。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3b8e64bde40f80a9997feeed8ede5800" data-id="3b8e64bde40f80a9997feeed8ede5800"><span><div id="3b8e64bde40f80a9997feeed8ede5800" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80a9997feeed8ede5800" title="连接主义"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">连接主义</span></span></h5><div class="notion-text notion-block-3b8e64bde40f80e19648f5512372be20">连接主义以人工神经网络研究为代表，通过构造人工神经网络模拟人脑的信息处理方式。它认为人的认知过程可以看作大量简单神经元构成的网络中的信息处理过程，而不只是符号运算。</div><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80959a8be0af3cc238b8"><li>代表成果：<span class="notion-red"><b>深度神经网络</b></span>、BP 反向传播、卷积神经网络、循环神经网络、生成式神经网络等。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80459466de26a8ee3f16"><li>典型事件：2015 年 ImageNet 图像识别挑战赛中，机器在识别正确率上达到很高水平。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80438d7cf83adb60a69c"><li>优点：<span class="notion-red"><b>能够从海量数据中学习，在图像处理、语音识别和自然语言处理等领域表现突出</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80aa8876d279045b1d89"><li>缺点：<span class="notion-red"><b>泛化能力有限、依赖大量样本，并且推理能力和可解释性相对不足</b></span>。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3b8e64bde40f802d8ea9eaaa4f76847a" data-id="3b8e64bde40f802d8ea9eaaa4f76847a"><span><div id="3b8e64bde40f802d8ea9eaaa4f76847a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f802d8ea9eaaa4f76847a" title="符号主义与连接主义融合"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">符号主义与连接主义融合</span></span></h5><div class="notion-text notion-block-3b8e64bde40f808e8f34e3f937d856be">符号主义擅长“推理”，连接主义擅长“学习”。<span class="notion-red"><b>将知识推理与数据学习结合</b></span>，是人工智能发展的重要方向。</div><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80ae9ee6fd75a44f4efc"><li>南京大学周志华教授提出“反绎学习（Abductive Learning）”，希望在一个框架内让机器学习与逻辑推理更均衡地协同。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80dd9d2ae570c42de64a"><li>清华大学张钹院士提出第三代 AI 的雏形，强调把数据驱动与知识推理结合，并进一步与人脑认知融合。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f800aa816d13fcc57b877" data-id="3b8e64bde40f800aa816d13fcc57b877"><span><div id="3b8e64bde40f800aa816d13fcc57b877" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f800aa816d13fcc57b877" title="从生物神经元到人工神经元"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">从生物神经元到人工神经元</span></span></h4><div class="notion-text notion-block-3b8e64bde40f80ca9fbce6263e8261f4">生物神经元可以粗略理解为“树突接收信息 → 细胞核处理信息 → 轴突输出信息 → 突触传递信息”。人工神经元使用类似的抽象：</div><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80c394eae91c66b583f9"><li>输入对应接收消息。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f801f9040fd8cdfd042a9"><li>加权求和对应信息处理。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80709c7de86ce89c6ecd"><li>激活函数提供非线性变换。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80dd8759d987b4d3a2f9"><li>输出继续传递给下一层神经元。</li></ul><div class="notion-text notion-block-3b8e64bde40f80e4b8c7d8768676248c">一个典型人工神经元的计算可以写成：</div><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><div class="notion-text notion-block-3b8e64bde40f805eb942eb8d8cd44a83">其中，<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是输入，<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是权重，<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是偏置，<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是激活函数。人工神经元的核心可以概括为“<span class="notion-red"><b>线性组合 + 非线性激活</b></span>”。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f8030b0efd223fb70d7e9" data-id="3b8e64bde40f8030b0efd223fb70d7e9"><span><div id="3b8e64bde40f8030b0efd223fb70d7e9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8030b0efd223fb70d7e9" title="前馈神经网络"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">前馈神经网络</span></span></h4><div class="notion-text notion-block-3b8e64bde40f8016a852f52c8f280a3a">前馈神经网络中，各层神经元按照输入层、隐藏层、输出层组织：</div><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80d09c2ed7082091af2e"><li>第 0 层称为<span class="notion-red"><b>输入层</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f806fa54ef2649d5755f2"><li>最后一层称为<span class="notion-red"><b>输出层</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80e692bcf95814b7faac"><li>中间层称为<span class="notion-red"><b>隐藏层</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8060983ec92f15de939d"><li>网络中不存在反馈回路，信号从输入层单向传播到输出层，因此可以用有向无环图表示。</li></ul><div class="notion-text notion-block-3b8e64bde40f8081b9e2c7db3317df69">隐藏层可表示为：</div><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><div class="notion-text notion-block-3b8e64bde40f802cb9b6e28e06a6e60e">输出层可表示为：</div><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><div class="notion-text notion-block-3b8e64bde40f8073b0e7e3be9df88d35">神经网络的一个重要优势是<span class="notion-red"><b>特征表示学习</b></span>：从原始、低层特征逐渐学习出中层和高层特征。例如在人脸相关任务中，可以从斑点、边缘逐渐形成鼻子、眼睛、脸颊等局部特征，最终形成“面部”这一更高层语义表示。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80eaaedae4f9f6b9afe9" data-id="3b8e64bde40f80eaaedae4f9f6b9afe9"><span><div id="3b8e64bde40f80eaaedae4f9f6b9afe9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80eaaedae4f9f6b9afe9" title="输出层与 Softmax"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">输出层与 Softmax</span></span></h4><div class="notion-text notion-block-3b8e64bde40f80bf9b4ae7e5e8b94a09">在分类任务中，输出层的作用可以看作分类器 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>：</div><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8093a658fe7e6e330097"><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>：最后一个隐藏层输出的高层特征。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8016a89eccb5f93a1011"><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>：分类器参数。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80afba07f34b3b9c5e36"><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>：各类别对应的输出概率。</li></ul><div class="notion-text notion-block-3b8e64bde40f80ffa368d6a394b7de5c">对于 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 分类问题，可以使用 Softmax 回归分类器：</div><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><div class="notion-text notion-block-3b8e64bde40f80b8a7dbd2a7472e59bd">其中，每个类别 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 对应一个参数向量 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>。网络最后一层通常是包含 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 个神经元的全连接层，再通过 Softmax 得到每个类别的条件概率。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f802eabdac1fe84afcd00" data-id="3b8e64bde40f802eabdac1fe84afcd00"><span><div id="3b8e64bde40f802eabdac1fe84afcd00" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f802eabdac1fe84afcd00" title="参数学习"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">参数学习</span></span></h4><div class="notion-text notion-block-3b8e64bde40f80a4a177fd11d017d357">前馈神经网络中的参数主要包括各隐藏层和输出层的权重参数。</div><div class="notion-text notion-block-3b8e64bde40f807d87fbc95976178214">例如，一个四分类任务中，输入特征维度为 4，网络包含 3 个隐藏层，隐藏层神经元个数分别为 5、10、5，且暂不考虑偏置项，则参数数量为：</div><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><div class="notion-text notion-block-3b8e64bde40f807e83e0ee8f81fd72a0">分类任务常使用交叉熵损失函数。对单个样本 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>：</div><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><div class="notion-text notion-block-3b8e64bde40f8086b046e813ebd955ed">其中，<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是标签的 one-hot 向量，<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是预测的类别概率向量。</div><div class="notion-text notion-block-3b8e64bde40f80f495cdc02cdf40bad0">整个训练集上的损失函数为：</div><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><div class="notion-text notion-block-3b8e64bde40f8014ae19e10ce21766f9">梯度下降每次迭代时，第 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 层参数的更新形式为：</div><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f802fbd25d16c7dca2b67" data-id="3b8e64bde40f802fbd25d16c7dca2b67"><span><div id="3b8e64bde40f802fbd25d16c7dca2b67" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f802fbd25d16c7dca2b67" title="反向传播与链式求导"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">反向传播与链式求导</span></span></h4><div class="notion-text notion-block-3b8e64bde40f80629561fd27fef5ad6a">反向传播的核心目标，是利用链式求导高效计算损失函数对网络参数的梯度。</div><div class="notion-text notion-block-3b8e64bde40f80f098f3f5f58b6a62ed">如果：</div><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><div class="notion-text notion-block-3b8e64bde40f800a9dc9ca531b66d459">标量情况下的链式法则为：</div><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><div class="notion-text notion-block-3b8e64bde40f804db414d41ff07b3820">扩展到向量形式，若 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>、<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>：</div><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><div class="notion-text notion-block-3b8e64bde40f80aba4f1e5f5dbc302e3">写成向量形式：</div><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><div class="notion-text notion-block-3b8e64bde40f8034964be9407b264fc4">其中 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是 Jacobian（雅可比）矩阵。</div><div class="notion-text notion-block-3b8e64bde40f80e2bc7bfe8ca9b1d338">在神经网络中，可以把前向计算表示成计算图。反向传播时，从损失函数开始沿计算图反向传播梯度，逐层计算参数梯度。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f8076a458e7af5ba3fe9a" data-id="3b8e64bde40f8076a458e7af5ba3fe9a"><span><div id="3b8e64bde40f8076a458e7af5ba3fe9a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8076a458e7af5ba3fe9a" title="自动微分"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">自动微分</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b8a3cee53b643a1859"><li>神经网络通常使用梯度下降优化参数。理论上可以手工按照链式法则逐个计算梯度，但手工求导并转换成程序过程繁琐、容易出错，且开发效率低。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80178f0acec65e226d4e"><li>主流深度学习框架因此提供<span class="notion-red"><b>自动微分能力</b></span>：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80178f0acec65e226d4e"><li>只需要描述网络结构和前向计算。</li><li>框架根据计算图和链式求导规则自动计算梯度。</li><li>TensorFlow、PyTorch、MindSpore 等都支持自动微分，但具体实现方式可能存在差异。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80debfcad87004421e8d" data-id="3b8e64bde40f80debfcad87004421e8d"><span><div id="3b8e64bde40f80debfcad87004421e8d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80debfcad87004421e8d" title="算子在神经网络中的含义"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">算子在神经网络中的含义</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b894d8e100797e98ff"><li>在神经网络和计算图中，<span class="notion-red"><b>算子对应计算图中的一层或一个节点的计算逻辑</b></span>。也可以理解为：<span class="notion-red"><b>每一个数据处理/数据计算的节点就是一个算子</b></span>。</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b894d8e100797e98ff"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3b8e64bde40f8082b433f87f665567d5"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3A44f14b7e-1a46-406f-9d5c-9cf2c14902b0%3A%E7%AE%97%E5%AD%90%E5%9C%A8%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E8%AE%A1%E7%AE%97%E5%9B%BE%E4%B8%AD%E7%9A%84%E8%A1%A8%E7%8E%B0.png?table=block&amp;id=3b8e64bd-e40f-8082-b433-f87f665567d5&amp;t=3b8e64bd-e40f-8082-b433-f87f665567d5" alt="算子在神经网络计算图中的表现" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">算子在神经网络计算图中的表现</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80919379c0db0ad66cf3"><li>一个神经网络通常由<span class="notion-red"><b>多个算子连接组成</b></span>，数据 Tensor 在算子之间流动。算子接收输入数据，完成某种计算，再产生输出数据。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f806cb0b4cf148be69d82" data-id="3b8e64bde40f806cb0b4cf148be69d82"><span><div id="3b8e64bde40f806cb0b4cf148be69d82" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f806cb0b4cf148be69d82" title="1-2 算子基本概念"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1-2 算子基本概念</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80a2bed8db11544fad7d" data-id="3b8e64bde40f80a2bed8db11544fad7d"><span><div id="3b8e64bde40f80a2bed8db11544fad7d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80a2bed8db11544fad7d" title="算子的数学含义"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">算子的数学含义</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8080a73fe1f87be165a7"><li>数学意义上的算子可以理解为一个函数空间到函数空间的映射：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8080a73fe1f87be165a7"><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80839049c7132ade2e15"><li>广义地说，<span class="notion-red"><b>对函数执行某种操作都可以看作一个算子</b></span>，例如微分算子、不定积分算子等。在深度学习中，tanh、ReLU、sigmoid 等<span class="notion-red"><b>函数也可以对应为具体计算算子</b></span>。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f805fb491f892abdd8763" data-id="3b8e64bde40f805fb491f892abdd8763"><span><div id="3b8e64bde40f805fb491f892abdd8763" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f805fb491f892abdd8763" title="算子基本组成"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">算子基本组成</span></span></h4><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3b8e64bde40f8008a56af22210a17268" data-id="3b8e64bde40f8008a56af22210a17268"><span><div id="3b8e64bde40f8008a56af22210a17268" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8008a56af22210a17268" title="算子名称（Name）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">算子名称（Name）</span></span></h5><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8012bd21e3a473b00ac1"><li>算子名称用于标识网络中的某个算子，<span class="notion-red"><b>同一网络中</b></span>的<span class="notion-red"><b>算子名称需要保持唯一</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a3b45aeba7db3a6033"><li>例如，一个网络中可以存在 <code class="notion-inline-code">Conv1</code>、<code class="notion-inline-code">Pool1</code>、<code class="notion-inline-code">Conv2</code>。其中 <code class="notion-inline-code">Conv1</code> 和 <code class="notion-inline-code">Conv2</code> 名称不同，但都可以属于 <code class="notion-inline-code">Convolution</code> 类型。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3b8e64bde40f80c4825aeea6839617a8" data-id="3b8e64bde40f80c4825aeea6839617a8"><span><div id="3b8e64bde40f80c4825aeea6839617a8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80c4825aeea6839617a8" title="算子类型（Type）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">算子类型（Type）</span></span></h5><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80129fecf44179844c06"><li>算子类型决定算子的实现逻辑。相同类型的算子实现逻辑相同，同一个网络中可以存在多个同类型算子。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3b8e64bde40f80dca20bd9dea39b123e" data-id="3b8e64bde40f80dca20bd9dea39b123e"><span><div id="3b8e64bde40f80dca20bd9dea39b123e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80dca20bd9dea39b123e" title="数据容器（Tensor）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">数据容器（Tensor）</span></span></h5><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8005931bdf6c2637fae9"><li>算子执行时需要输入数据，执行完成后会产生输出数据。承载输入、输出数据的容器称为 <span class="notion-red"><b>Tensor（张量）</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f801b81c3c72022a8c2c6"><li><span class="notion-red"><b>Tensor 是实际数据的容器</b></span>，而 TensorDesc 是对输入、输出数据的描述。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f805d8974e629ff4b7812" data-id="3b8e64bde40f805d8974e629ff4b7812"><span><div id="3b8e64bde40f805d8974e629ff4b7812" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f805d8974e629ff4b7812" title="Tensor 与 TensorDesc"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Tensor 与 TensorDesc</span></span></h4><table class="notion-simple-table notion-block-3b8e64bde40f801f98e3e58d46266800"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3b8e64bde40f805782b8d50ab2cd5380"><td class="" style="width:353.5px"><div class="notion-simple-table-cell">属性</div></td><td class="" style="width:353.5px"><div class="notion-simple-table-cell">定义</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f808cb26bd7f093b04eec"><td class="" style="width:353.5px"><div class="notion-simple-table-cell">名称（name）</div></td><td class="" style="width:353.5px"><div class="notion-simple-table-cell">用于对 Tensor 进行索引，不同 Tensor 的 <code class="notion-inline-code">name</code> 需要保持唯一</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f8061a012d7edc3a16110"><td class="" style="width:353.5px"><div class="notion-simple-table-cell">形状（shape）</div></td><td class="" style="width:353.5px"><div class="notion-simple-table-cell">描述 Tensor 的形状，例如 <code class="notion-inline-code">(10,)</code>、<code class="notion-inline-code">(1024, 1024)</code>、<code class="notion-inline-code">(2, 3, 4)</code> 等</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f808187fec4dd6ce2c682"><td class="" style="width:353.5px"><div class="notion-simple-table-cell">数据类型（dtype）</div></td><td class="" style="width:353.5px"><div class="notion-simple-table-cell">指定 Tensor 对象的数据类型，例如 <code class="notion-inline-code">float16</code>、<code class="notion-inline-code">float32</code>、<code class="notion-inline-code">int8</code>、<code class="notion-inline-code">int16</code>、<code class="notion-inline-code">int32</code>、<code class="notion-inline-code">uint8</code>、<code class="notion-inline-code">uint16</code>、<code class="notion-inline-code">bool</code> 等；不同计算操作支持的数据类型可能不同</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f807786e2d7b8cf2668c6"><td class="" style="width:353.5px"><div class="notion-simple-table-cell">数据排布格式（format）</div></td><td class="" style="width:353.5px"><div class="notion-simple-table-cell">数据的物理排布格式，用于定义如何解释各个维度的数据</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80f7a3c0d612302547be" data-id="3b8e64bde40f80f7a3c0d612302547be"><span><div id="3b8e64bde40f80f7a3c0d612302547be" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80f7a3c0d612302547be" title="Shape"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Shape</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80cb8404f4735dc387a9"><li>张量的形状通常写作：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80cb8404f4735dc387a9"><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8020a47ef826d7780732"><li>括号中有多少个维度值，就代表该 Tensor 是多少维。每一个维度的值表示该维度包含多少个元素。</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8020a47ef826d7780732"><table class="notion-simple-table notion-block-3b8e64bde40f80749238e3c152b0701f"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3b8e64bde40f80288f6fd86a84dd357d"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">张量示例</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">Shape</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f8009b059fdc0cb87edd3"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">1</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">(0,)</code></div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f803f8962f91e91b6e156"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">[1,2,3]</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">(3,)</code></div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f803092d1f38a6c30acd2"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">[[1,2],[3,4]]</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">(2,2)</code></div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f807d8058ccdec6af2d69"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">[[[1,2],[3,4]], [[5,6],[7,8]]]</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">(2,2,2)</code></div></td></tr></tbody></table></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80e6bb43d4c9a7af4b71"><li>例如 <code class="notion-inline-code">shape=(4,20,20,3)</code> 可以理解为：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80e6bb43d4c9a7af4b71"><li>有 4 张图片。</li><li>每张图片的高度为 20、宽度为 20，即每张图有 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 个像素。</li><li>每个像素由 3 个通道组成，例如 RGB 三通道。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80118869f7041c526e6a"><li>从程序角度看，多维 Tensor 可以理解为嵌套的多层循环；对某个元素的访问最终会映射为线性内存中的地址计算。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f8012881dcdd7dafc489b" data-id="3b8e64bde40f8012881dcdd7dafc489b"><span><div id="3b8e64bde40f8012881dcdd7dafc489b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8012881dcdd7dafc489b" title="Format"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Format</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8045b65efd515ba07a3e"><li>深度学习中的多维数据最终仍需要在线性内存中存储，因此维度顺序会影响数据的物理排布。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f809a897cf3a7967fea37"><li>卷积神经网络中的 Feature Map 常使用 4D 格式，其中：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f809a897cf3a7967fea37"><li><code class="notion-inline-code">N</code>：Batch 数量，例如图片数量。</li><li><code class="notion-inline-code">H</code>：Height，特征图高度。</li><li><code class="notion-inline-code">W</code>：Width，特征图宽度。</li><li><code class="notion-inline-code">C</code>：Channels，特征图通道数，例如 RGB 图像的通道数为 3。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f807588a5d23724e20d4b"><li>常见排布包括：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f807588a5d23724e20d4b"><table class="notion-simple-table notion-block-3b8e64bde40f80159a81ec2a4078fd74"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3b8e64bde40f80dd863ef867eaaa3896"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">Format</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">维度顺序</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">特点</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80aeae3feffc3062a02a"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">NCHW</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell"><code class="notion-inline-code">[Batch, Channels, Height, Width]</code></div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">同一通道的数据在内存中更集中，例如 RGB 图像可表现为先连续存 R，再连续存 G，再连续存 B</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f8016ba3acd3955376d63"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">NHWC</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell"><code class="notion-inline-code">[Batch, Height, Width, Channels]</code></div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">通道维位于最内层，同一像素位置的多个通道值相邻存储，例如 <code class="notion-inline-code">RGBRGBRGB...</code></div></td></tr></tbody></table></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80079db5e5bd4ac58538" data-id="3b8e64bde40f80079db5e5bd4ac58538"><span><div id="3b8e64bde40f80079db5e5bd4ac58538" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80079db5e5bd4ac58538" title="axis"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">axis</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8031acf6d4b2fd2d24bc"><li><code class="notion-inline-code">axis</code> 表示 Tensor 中某一个维度的下标。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f802caf39c0d46d7a1e7c"><li>如果 Tensor 的 <code class="notion-inline-code">shape=(5,6)</code>：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f802caf39c0d46d7a1e7c"><li><code class="notion-inline-code">axis=0</code> 表示第一维，即“行”。</li><li><code class="notion-inline-code">axis=1</code> 表示第二维，即“列”。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80009752cf4a4a5d199c"><li>例如数据：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80009752cf4a4a5d199c"></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80d4b625f65b9e27ed47"><li>其 <code class="notion-inline-code">shape=(2,2,2)</code>：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80d4b625f65b9e27ed47"><li>轴 0 对应最外层的两个矩阵。</li><li>轴 1 对应 <code class="notion-inline-code">[1,2]</code>、<code class="notion-inline-code">[3,4]</code>、<code class="notion-inline-code">[5,6]</code>、<code class="notion-inline-code">[7,8]</code> 这一级数据。</li><li>轴 2 对应最内层的标量 <code class="notion-inline-code">1,2,3,4,5,6,7,8</code>。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80698cf3cfe61716bf47"><li><code class="notion-inline-code">axis</code> 也可以使用负数，从最后一个维度反向编号。对于 <code class="notion-inline-code">shape=(4,20,20,3)</code>：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80698cf3cfe61716bf47"><table class="notion-simple-table notion-block-3b8e64bde40f800db15edfa550efe31c"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3b8e64bde40f80ca9360e354e1a15e82"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">正向 axis</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">负向 axis</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f802a90a8f1f865ab1ae0"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">0</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">-4</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f801a9bcbc7099eb41d26"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">1</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">-3</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80ec9b32de8201e7a6b4"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">2</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">-2</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80a9b595ee91a5d5a06b"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">3</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">-1</div></td></tr></tbody></table></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80568b75f9b0ec2653de"><li>对于 N 维 Tensor，正向轴编号为 <code class="notion-inline-code">0,1,2,...,N-1</code>。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f802b9321e20f1dbf51f0" data-id="3b8e64bde40f802b9321e20f1dbf51f0"><span><div id="3b8e64bde40f802b9321e20f1dbf51f0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f802b9321e20f1dbf51f0" title="1-3 算子运行演示"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1-3 算子运行演示</span></span></h3><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80679285cb616340f599"><li><code class="notion-inline-code">run.sh</code> 的执行过程可以概括为：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80679285cb616340f599"><ol start="1" class="notion-list notion-list-numbered notion-block-3b8e64bde40f806583b5f54470aac8e3" style="list-style-type:decimal"><li>编译 <code class="notion-inline-code">add_custom</code> 算子。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3b8e64bde40f80008829f544746d1bfb" style="list-style-type:decimal"><li>编译算子调用方法 <code class="notion-inline-code">main.cpp</code>。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3b8e64bde40f807abcc0c18c2292b11c" style="list-style-type:decimal"><li>执行 <code class="notion-inline-code">scripts</code> 目录中的数据生成逻辑，调用 <code class="notion-inline-code">main.cpp</code> 拉起算子计算，并将算子结果与预期结果进行比较，判断计算是否正确。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a5b708d25428cc8e79"><li>因此，一个最小算子样例通常包含“<span class="notion-red"><b>算子实现 → 编译 → Host 侧调用 → 输入数据准备 → 执行 → 结果校验</b></span>”这一完整链路。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f80c68e96e8dab7266e10" data-id="3b8e64bde40f80c68e96e8dab7266e10"><span><div id="3b8e64bde40f80c68e96e8dab7266e10" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80c68e96e8dab7266e10" title="1-4 算子开发的问题与挑战"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1-4 算子开发的问题与挑战</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f806cbe00e0afdbbe5fc7" data-id="3b8e64bde40f806cbe00e0afdbbe5fc7"><span><div id="3b8e64bde40f806cbe00e0afdbbe5fc7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f806cbe00e0afdbbe5fc7" title="算子开发的复杂性"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">算子开发的复杂性</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8046be76f7d2842d36db"><li>实现一个算子时，开发者不仅要“把数学公式写成代码”，还要同时考虑多个层面：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8046be76f7d2842d36db"><li>功能逻辑如何实现。</li><li>如何处理不同大小的输入。</li><li>如何处理不同类型的输入。</li><li>如何适配目标硬件。</li><li>如何保证算子运行性能。</li><li>如何优化算子的数学公式与计算过程。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f803cbc89ca1d745c88fe" data-id="3b8e64bde40f803cbc89ca1d745c88fe"><span><div id="3b8e64bde40f803cbc89ca1d745c88fe" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f803cbc89ca1d745c88fe" title="功能逻辑实现：以激活函数为例"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">功能逻辑实现：以激活函数为例</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8021809bcef7b1708f8c"><li>即使都是“激活函数”，不同函数的适用场景、性能特征以及对精度的影响也并不相同。因此，算子设计不能只关注“能否算对”，<span class="notion-red"><b>还需要考虑同一功能可能存在的多种实现方式</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80d0a90ecc17340313d1"><li>典型激活函数包括：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80d0a90ecc17340313d1"><li><code class="notion-inline-code">tanh</code></li><li><code class="notion-inline-code">ReLU</code></li><li><code class="notion-inline-code">sigmoid</code></li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80d7a2afdf6398a28181" data-id="3b8e64bde40f80d7a2afdf6398a28181"><span><div id="3b8e64bde40f80d7a2afdf6398a28181" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80d7a2afdf6398a28181" title="与硬件结合：以 Flash Attention 为例"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">与硬件结合：以 Flash Attention 为例</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a984cef25374aba1b6"><li>高性能算子需要结合硬件存储层次和计算资源设计。Flash Attention 的核心思路之一，是减少高层、低带宽存储与片上高速存储之间的数据搬运，把更适合局部计算的数据块放到更靠近计算单元的高速存储中处理。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f805dab56ede3ce10f0fa"><li>在昇腾硬件上，还需要同时考虑：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f805dab56ede3ce10f0fa"><li><b>核间并行</b>：把不同数据块<span class="notion-red"><b>分配给多个 AI Core 并行执行</b></span>。</li><li><b>核内并行</b>：<span class="notion-red"><b>协调 Scalar、Vector、Cube、DMA/搬运等不同单元</b></span>，使计算与数据搬运尽可能重叠。</li></ul></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3b8e64bde40f8030b33bf896ca72449f"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3Acc775048-39f1-4f20-94d4-a381aad6d72b%3AFlash_Attention_%E4%B8%8E%E7%A1%AC%E4%BB%B6%E5%AD%98%E5%82%A8%E8%AE%A1%E7%AE%97%E8%B5%84%E6%BA%90%E7%9A%84%E7%BB%93%E5%90%88.png?table=block&amp;id=3b8e64bd-e40f-8030-b33b-f896ca72449f&amp;t=3b8e64bd-e40f-8030-b33b-f896ca72449f" alt="Flash Attention 与硬件存储/计算资源的结合" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">Flash Attention 与硬件存储/计算资源的结合</figcaption></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f8052b6e1d10c06844cfd" data-id="3b8e64bde40f8052b6e1d10c06844cfd"><span><div id="3b8e64bde40f8052b6e1d10c06844cfd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8052b6e1d10c06844cfd" title="性能优化：提高流水并行度"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">性能优化：提高流水并行度</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8084baa0d71e3c004cdd"><li>以 Flash Attention 的性能优化为例，在对缓存中的 <code class="notion-inline-code">mm1/mm2/mm3</code> 等计算进行优化后，可以在本轮 Vector 与 Cube 流水的间隔中，<span class="notion-red"><b>提前插入下一轮循环的 Vector 计算</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8020bc14ffa5c8a4ff0c"><li>这样可以让 <span class="notion-red"><b>Vector 流水和 Cube 流水之间的并行度更高</b></span>，在流水图中表现为 Vector 计算更加密集，从而提升整体资源利用率和执行性能。</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3b8e64bde40f800c9f5fc3b07c61a31e" data-id="3b8e64bde40f800c9f5fc3b07c61a31e"><span><div id="3b8e64bde40f800c9f5fc3b07c61a31e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f800c9f5fc3b07c61a31e" title="2-什么是Ascend C"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2-什么是Ascend C</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f80a7879fd88a17e83130" data-id="3b8e64bde40f80a7879fd88a17e83130"><span><div id="3b8e64bde40f80a7879fd88a17e83130" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80a7879fd88a17e83130" title="2-1CANN 与 Ascend C"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2-1CANN 与 Ascend C</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80568d1ecb6f2c42ec12" data-id="3b8e64bde40f80568d1ecb6f2c42ec12"><span><div id="3b8e64bde40f80568d1ecb6f2c42ec12" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80568d1ecb6f2c42ec12" title="CANN 在昇腾 AI 软件栈中的位置"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">CANN 在昇腾 AI 软件栈中的位置</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80aa9608df99d124ac5d"><li>CANN 是面向昇腾 AI 处理器的异构计算架构，向上承接深度学习框架、AI 框架适配、创新算子与领域加速库、人工智能应用，向下连接 Runtime、驱动和昇腾 AI 处理器。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f802daa13c680915f2c21"><li>在 CANN 中，典型组件包括：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f802daa13c680915f2c21"><li><b>GE 图引擎</b>：计算图编译运行控制中心，提供图编译优化与加载执行能力。</li><li><b>Ascend C 算子开发语言</b>：面向算子开发场景，支持算子级编程。</li><li><b>AOL 算子加速库</b>：提供经过深度优化的高性能算子。</li><li><b>HCCL 集合通信库</b>：提供单机多卡及多机多卡的数据并行、模型并行等集合通信能力。</li><li><b>Runtime 运行时</b>：提供资源管理、媒体数据预处理、模型推理等基础能力。</li><li><b>MindStudio</b>：提供全流程开发工具链。</li></ul></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3b8e64bde40f80ed95b8f3541ce64fd2"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3A2ab17157-830a-45ba-8000-fece5427023c%3ACANN_%E4%B8%8E_Ascend_C_%E5%9C%A8%E6%98%87%E8%85%BE_AI_%E8%BD%AF%E4%BB%B6%E6%A0%88%E4%B8%AD%E7%9A%84%E4%BD%8D%E7%BD%AE.png?table=block&amp;id=3b8e64bd-e40f-80ed-95b8-f3541ce64fd2&amp;t=3b8e64bd-e40f-80ed-95b8-f3541ce64fd2" alt="CANN 与 Ascend C 在昇腾 AI 软件栈中的位置" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">CANN 与 Ascend C 在昇腾 AI 软件栈中的位置</figcaption></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f804b8771e525037508b9" data-id="3b8e64bde40f804b8771e525037508b9"><span><div id="3b8e64bde40f804b8771e525037508b9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f804b8771e525037508b9" title="什么是 Ascend C"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">什么是 Ascend C</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f803fb365e25c92416995"><li>Ascend C 是 CANN 针对算子开发场景推出的编程语言。它通过多层接口抽象、自动并行计算、孪生调试等关键技术，提高算子开发效率，帮助开发者以较低成本完成算子开发和模型调优部署。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8082887fce1725186e09"><li>使用 Ascend C 编程语言开发的算子称为 <span class="notion-red"><b>Ascend C 算子</b></span>。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f8060af8aea9108269d92" data-id="3b8e64bde40f8060af8aea9108269d92"><span><div id="3b8e64bde40f8060af8aea9108269d92" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8060af8aea9108269d92" title="使用 Ascend C 开发自定义算子的优势"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">使用 Ascend C 开发自定义算子的优势</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80159f7ce9d4b20c2a3f"><li><span class="notion-red"><b>C/C++ 原语编程</b></span>：最大化匹配开发者已有的 C/C++ 开发习惯。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b1b340d0ac3dee59bc"><li><span class="notion-red"><b>屏蔽硬件差异</b></span>：通过编程模型抽象硬件差异，提高开发效率。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80ae947ac8a5a92ba8cd"><li><span class="notion-red"><b>多层级 API 封装</b></span>：从灵活的底层控制到高层易用接口，兼顾灵活性与效率。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b8b0dffb2774e64ffc"><li><span class="notion-red"><b>孪生调试</b></span>：可在 CPU 侧模拟 NPU 侧行为，优先在 CPU 环境中进行功能和精度调试。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f80c19f9deb077ebb4bd3" data-id="3b8e64bde40f80c19f9deb077ebb4bd3"><span><div id="3b8e64bde40f80c19f9deb077ebb4bd3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80c19f9deb077ebb4bd3" title="2-2 昇腾 AI 处理器架构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2-2 昇腾 AI 处理器架构</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f8077ac2edd6ffc3ad4c3" data-id="3b8e64bde40f8077ac2edd6ffc3ad4c3"><span><div id="3b8e64bde40f8077ac2edd6ffc3ad4c3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8077ac2edd6ffc3ad4c3" title="昇腾 AI 处理器逻辑架构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">昇腾 AI 处理器逻辑架构</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80639ad1ee92c171424e"><li>昇腾 AI 处理器的逻辑架构主要包括：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80639ad1ee92c171424e"><li><span class="notion-red"><b>系统控制处理器（Control CPU）</b></span>：负责系统控制相关任务。</li><li><span class="notion-red"><b>AI Core</b></span>：面向计算密集型任务的 AI 计算核心。</li><li><span class="notion-red"><b>AI CPU</b></span>：面向非矩阵类计算任务的 AI 处理器。</li><li><span class="notion-red"><b>任务调度器 TS</b></span>：负责相关任务调度。</li><li><span class="notion-red"><b>层次化片上缓存/缓冲区</b></span>：为计算单元提供高带宽数据访问。</li><li><span class="notion-red"><b>数字视觉预处理模块（DVPP）</b></span>：完成数字视觉相关预处理。</li><li><span class="notion-red"><b>I/O 接口</b></span>：负责外部数据与设备连接。</li><li><span class="notion-red"><b>DDR/HBM 接口</b></span>：连接外部高容量内存。</li></ul></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3b8e64bde40f8032bb54cd8a51ca7f3d"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3Afd854ad7-73c4-4b9c-8665-7062d25a5b8c%3A%E6%98%87%E8%85%BE_AI_%E5%A4%84%E7%90%86%E5%99%A8%E9%80%BB%E8%BE%91%E6%9E%B6%E6%9E%84.png?table=block&amp;id=3b8e64bd-e40f-8032-bb54-cd8a51ca7f3d&amp;t=3b8e64bd-e40f-8032-bb54-cd8a51ca7f3d" alt="昇腾 AI 处理器逻辑架构" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">昇腾 AI 处理器逻辑架构</figcaption></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80b7addec8fa55f8edd6" data-id="3b8e64bde40f80b7addec8fa55f8edd6"><span><div id="3b8e64bde40f80b7addec8fa55f8edd6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80b7addec8fa55f8edd6" title="AI Core 与达芬奇架构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">AI Core 与达芬奇架构</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80498c89e81888cccaf0"><li>AI Core 是昇腾 AI 处理器的计算核心，采用华为自研的达芬奇架构（DaVinci Core）。不同处理器版本中的计算、存储和带宽资源规格可能不同，但总体可以划分为三大部分：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80498c89e81888cccaf0"><li><span class="notion-red"><b>计算单元</b></span>：包含矩阵计算单元、向量计算单元、标量计算单元等基础计算资源。</li><li><span class="notion-red"><b>存储系统</b></span>：由 AI Core 的片上存储单元以及相应数据通路组成，为计算单元提供数据。</li><li><span class="notion-red"><b>控制单元</b></span>：负责整个计算过程的指令控制，相当于 AI Core 的“司令部”。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f805cb733db615754bda2"><li>从具体数据通路看，AI Core 中会涉及 L1 Buffer、Unified Buffer、矩阵输入/输出 Buffer、Vector/Scalar 计算资源以及搬运单元等。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80b78e5bcc8506ab776e" data-id="3b8e64bde40f80b78e5bcc8506ab776e"><span><div id="3b8e64bde40f80b78e5bcc8506ab776e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80b78e5bcc8506ab776e" title="耦合架构与分离架构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">耦合架构与分离架构</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f809f8c8af04868555183"><li>Ascend AI Core 可以采用不同的计算资源组织方式。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3b8e64bde40f80e4846ad115ca8cd94d" data-id="3b8e64bde40f80e4846ad115ca8cd94d"><span><div id="3b8e64bde40f80e4846ad115ca8cd94d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80e4846ad115ca8cd94d" title="耦合架构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">耦合架构</span></span></h5><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f806db969d886d9881a87"><li>Cube、Vector、Scalar 等资源集成在同一 AI Core 中，数据可通过 L1 Buffer、Unified Buffer 等片上存储协同流动。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3b8e64bde40f8013999feec017800a58" data-id="3b8e64bde40f8013999feec017800a58"><span><div id="3b8e64bde40f8013999feec017800a58" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8013999feec017800a58" title="分离架构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">分离架构</span></span></h5><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8079af59ed2be037b3d5"><li>计算资源可进一步拆分为不同类型的核心：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8079af59ed2be037b3d5"><li><span class="notion-red"><b>AIC</b></span>：以 <span class="notion-red"><b>Cube 矩阵计算</b></span>为主要资源。</li><li><span class="notion-red"><b>AIV</b></span>：以 <span class="notion-red"><b>Vector 向量计算</b></span>为主要资源。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f804190c5f6f37709b26f"><li>AIC 与 AIV 可按照一定比例组织，使矩阵计算和向量计算资源更加独立地调度和利用。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f8013a8ceec6c82cf1491" data-id="3b8e64bde40f8013a8ceec6c82cf1491"><span><div id="3b8e64bde40f8013a8ceec6c82cf1491" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8013a8ceec6c82cf1491" title="2-3Ascend C 的特点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2-3Ascend C 的特点</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f809bb706e75e975cf9e2" data-id="3b8e64bde40f809bb706e75e975cf9e2"><span><div id="3b8e64bde40f809bb706e75e975cf9e2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f809bb706e75e975cf9e2" title="开发效率提升"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">开发效率提升</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a7b66ae4ed0e8d3c55"><li>传统算子开发存在较高门槛，典型难点包括：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a7b66ae4ed0e8d3c55"><li>程序语义如何映射到复杂指令序列。</li><li>数据存储空间如何分配、释放和复用。</li><li>如何实现数据和计算流水并行。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f802999d0cf7f7a2a38a8"><li>Ascend C 通过编程抽象降低这些门槛，典型场景中可以显著缩短算子开发周期。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a9890ee140e6866308"><li>其核心特点可以概括为：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a9890ee140e6866308"><li><span class="notion-red"><b>遵循 C/C++ 标准规范</b></span>。</li><li><span class="notion-red"><b>自动化流水并行调度</b></span>。</li><li><span class="notion-red"><b>结构化核函数编程</b></span>。</li><li><span class="notion-red"><b>CPU/NPU 孪生调试</b></span>。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f8057b26be00f8b66d186" data-id="3b8e64bde40f8057b26be00f8b66d186"><span><div id="3b8e64bde40f8057b26be00f8b66d186" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8057b26be00f8b66d186" title="采用标准 C++ 语法，基于类库 API 编程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">采用标准 C++ 语法，基于类库 API 编程</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80278890f22091f22032"><li>Ascend C 使用标准 C++ 语法，并通过类库 API 提供算子开发能力。常见 API 类型包括：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80278890f22091f22032"><li>向量计算 API。</li><li>矩阵计算 API。</li><li>数据搬运 API。</li><li>内存管理 API。</li><li>任务同步 API。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80238350ec8b5248abc5"><li>基本数据类型包括 <code class="notion-inline-code">GlobalTensor</code>、<code class="notion-inline-code">LocalTensor</code> 等。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8079be07fb5d7a5e1f6c"><li>计算 API 采用分层设计：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8079be07fb5d7a5e1f6c"><table class="notion-simple-table notion-block-3b8e64bde40f8040aa46e537a692f8f8"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3b8e64bde40f801d81c2ca6e3bc35cb9"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">API 层级</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">主要特点</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">示例</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f808c98a4c03ed986e5b9"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">0 级 API</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">功能灵活，可显式控制较多底层操作</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Add(dst, src1, src2, mask, repeatTimes, repeatParams)</code></div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80c395e9ef92abdfd882"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">1 级 slice 计算 API</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">面向多维数据切片计算</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">解决多维数据切片计算问题</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80d09f7fe1ea528a386e"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">2 级连续计算 API</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">对 Tensor 指定长度的连续数据进行计算</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Add(dst, src1, src2, count)</code></div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80ad9e7ce2a5d39a913f"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">3 级 API</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">运算符重载，表达更接近普通 C++</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell"><code class="notion-inline-code">dst = src1 + src2</code></div></td></tr></tbody></table></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80d3b1b1d205899e13d3"><li>API 层级越高，一般自由度越低，但易用性越高；层级越低，控制粒度更细、自由度更高。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f8007a49ec25a146791e3" data-id="3b8e64bde40f8007a49ec25a146791e3"><span><div id="3b8e64bde40f8007a49ec25a146791e3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8007a49ec25a146791e3" title="核间支持 SPMD 数据并行"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">核间支持 SPMD 数据并行</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f803f812ece96ffe4d63d"><li>Ascend C 支持 <span class="notion-red"><b>SPMD（Single-Program Multiple-Data）</b></span>数据并行：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f803f812ece96ffe4d63d"><li>将待处理数据拆分并分发到多个计算核心。</li><li>多个 AI Core 运行相同的指令代码，但处理不同的数据分片。</li><li>每个核通过不同的 <code class="notion-inline-code">block_idx</code> 区分自己需要处理的数据。</li><li>开发者重点关注单核算子实现，再由并行模型将工作扩展到多核。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80998e4be34ba3475e72" data-id="3b8e64bde40f80998e4be34ba3475e72"><span><div id="3b8e64bde40f80998e4be34ba3475e72" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80998e4be34ba3475e72" title="核内支持自动化流水并行"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">核内支持自动化流水并行</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f808fa0a1daed90a8ae2d"><li>Ascend C 将算子核内处理过程拆分为多个流水任务（Stage），典型阶段是：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f808fa0a1daed90a8ae2d"><ol start="1" class="notion-list notion-list-numbered notion-block-3b8e64bde40f80c88323fbf1cb6f9f55" style="list-style-type:decimal"><li><span class="notion-red"><b>搬入（CopyIn）</b></span>：将输入数据从 Global Memory 搬入 Local Memory。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3b8e64bde40f80afa289f4028c8c168c" style="list-style-type:decimal"><li><span class="notion-red"><b>计算（Compute）</b></span>：使用 Local Memory 中的数据进行计算。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3b8e64bde40f80eea0a8ef9dc75f6247" style="list-style-type:decimal"><li><span class="notion-red"><b>搬出（CopyOut）</b></span>：将计算结果从 Local Memory 搬回 Global Memory。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8033b56bc0ee86791a28"><li>其中：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8033b56bc0ee86791a28"><li>Tensor 作为数据载体。</li><li>Queue 用于不同任务之间的通信和同步。</li><li>Pipe 用于管理任务间的通信内存。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f800fb79fda7b23ce1d81"><li>通过多片数据流水调度，可以让“搬入、计算、搬出”阶段交叠执行，提高计算与搬运资源的并行度。</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3b8e64bde40f8028817ed0c95deb35c6"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3Abe9f7567-933a-4f09-929e-6e9b5f4c9707%3AAscend_C_%E6%A0%B8%E5%86%85%E6%B5%81%E6%B0%B4%E5%B9%B6%E8%A1%8C.png?table=block&amp;id=3b8e64bd-e40f-8028-817e-d0c95deb35c6&amp;t=3b8e64bd-e40f-8028-817e-d0c95deb35c6" alt="Ascend C 核内流水并行" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">Ascend C 核内流水并行</figcaption></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80699aafee0d7c33eed5" data-id="3b8e64bde40f80699aafee0d7c33eed5"><span><div id="3b8e64bde40f80699aafee0d7c33eed5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80699aafee0d7c33eed5" title="结构化核函数编程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">结构化核函数编程</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b78083c81383d704dd"><li>Ascend C 提供结构化的算子实现框架，典型逻辑为：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b78083c81383d704dd"></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b8ad04d748977285b5"><li>各阶段职责：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b8ad04d748977285b5"><li><code class="notion-inline-code">Init</code>：完成<span class="notion-red"><b>内存初始化</b></span>、<span class="notion-red"><b>队列等资源创建</b></span>。</li><li><code class="notion-inline-code">CopyIn</code>：输入数据从 Global Memory 搬到 Local Memory。</li><li><code class="notion-inline-code">Compute</code>：使用 Local Memory 中的数据完成计算。</li><li><code class="notion-inline-code">CopyOut</code>：结果从 Local Memory 搬回 Global Memory。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a09ae4e75d1ade0329"><li>这种结构有利于快速搭建算子实现代码框架，并与流水并行模型自然对应。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80609acedc4583f3cd31" data-id="3b8e64bde40f80609acedc4583f3cd31"><span><div id="3b8e64bde40f80609acedc4583f3cd31" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80609acedc4583f3cd31" title="异构混合编程：Host/Device 灵活通信"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">异构混合编程：Host/Device 灵活通信</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8037bc07d4bb89d090c9"><li>昇腾 AI 异构计算中，CPU 与 NPU 协同工作。Ascend C 编程模型通常需要分别实现：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8037bc07d4bb89d090c9"><li><span class="notion-red"><b>Host 侧代码</b></span>：负责初始化、资源申请、数据传输、核函数启动、同步、资源释放等。</li><li><span class="notion-red"><b>Device 侧代码</b></span>：在 AI Core 上执行具体算子计算。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f803f8782d25987502c3a"><li>典型执行流程：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f803f8782d25987502c3a"><ol start="1" class="notion-list notion-list-numbered notion-block-3b8e64bde40f802195a8cf8b28d8254a" style="list-style-type:decimal"><li>AscendCL 初始化。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3b8e64bde40f80219399cd96b862113e" style="list-style-type:decimal"><li>申请运行管理资源。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3b8e64bde40f80e391c5e724e0e1d4f1" style="list-style-type:decimal"><li>Host 数据传输到 Device。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3b8e64bde40f80c3a953d88b868d8031" style="list-style-type:decimal"><li>调用核函数完成指定运算。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3b8e64bde40f807ea7dce752bc7cc82d" style="list-style-type:decimal"><li>Device 数据传回 Host。</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3b8e64bde40f807597f8e342a000f731" style="list-style-type:decimal"><li>释放运行管理资源。</li></ol><ol start="7" class="notion-list notion-list-numbered notion-block-3b8e64bde40f80049313eb10105fa22d" style="list-style-type:decimal"><li>AscendCL 去初始化。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b49181fbff6fa9453f"><li>核函数通过扩展调用语法启动：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b49181fbff6fa9453f"></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f804cbef1dec858f1f225"><li>其中：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f804cbef1dec858f1f225"><li><code class="notion-inline-code">blockDim</code>：执行核数。</li><li><code class="notion-inline-code">nullptr</code>：保留参数。</li><li><code class="notion-inline-code">stream</code>：用于异步任务调度的任务流。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f8097b859cc22f97e155b" data-id="3b8e64bde40f8097b859cc22f97e155b"><span><div id="3b8e64bde40f8097b859cc22f97e155b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8097b859cc22f97e155b" title="CPU/NPU 孪生调试"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">CPU/NPU 孪生调试</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80df95d2e34030386465"><li>传统方式在 NPU 环境中调试时，常面临调试耗时长、并发和地址问题定位困难等问题。Ascend C 支持 CPU/NPU 孪生调试：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80df95d2e34030386465"><li><span class="notion-red"><b>CPU 域调试</b></span>：重点验证功能和精度，可使用 GDB、<code class="notion-inline-code">printf</code>/<code class="notion-inline-code">cout</code>、<code class="notion-inline-code">ASSERT</code> 等方式，定位逻辑错误、数据计算错误和内存问题。</li><li><span class="notion-red"><b>NPU 域调试</b></span>：重点验证真实性能和硬件执行行为，可使用 Profiling 流水图、指令日志、数据日志、板上执行时间统计等手段，定位性能问题和算子同步问题。</li></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3b8e64bde40f8081bc9df90b0b0130bf" data-id="3b8e64bde40f8081bc9df90b0b0130bf"><span><div id="3b8e64bde40f8081bc9df90b0b0130bf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8081bc9df90b0b0130bf" title="3-算子开发初体验"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3-算子开发初体验</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f80c98d46e69bebbc3b8c" data-id="3b8e64bde40f80c98d46e69bebbc3b8c"><span><div id="3b8e64bde40f80c98d46e69bebbc3b8c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80c98d46e69bebbc3b8c" title="3-1Host 与 Device"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3-1Host 与 Device</span></span></h3><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f800da999ecea26b01e58"><li>在 Ascend C 算子开发中，Host 与 Device 构成典型的异构计算系统。</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f800da999ecea26b01e58"><li><span class="notion-red"><b>Host</b></span>：与 Device 相连接的 X86 或 ARM 服务器，负责运行 Host 侧程序，并利用 Device 提供的神经网络计算能力完成任务。</li><li><span class="notion-red"><b>Device</b></span>：安装了昇腾 AI 处理器的硬件设备，通过 PCIe 等接口与 Host 连接，提供 NPU 计算能力。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80e8b731c5ddda07312b"><li>Device 上包含一个或多个 AI Core，并通过 Global Memory（例如 DDR）存储大容量数据。</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3b8e64bde40f8095a717da67f466e101"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3A88f25a7b-7941-48ee-adfa-879400a40a3a%3AHost_%E4%B8%8E_Device_%E7%9A%84%E5%85%B3%E7%B3%BB.png?table=block&amp;id=3b8e64bd-e40f-8095-a717-da67f466e101&amp;t=3b8e64bd-e40f-8095-a717-da67f466e101" alt="Host 与 Device 的关系" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">Host 与 Device 的关系</figcaption></div></figure><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f80a1a43eea64b2c4eeef" data-id="3b8e64bde40f80a1a43eea64b2c4eeef"><span><div id="3b8e64bde40f80a1a43eea64b2c4eeef" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80a1a43eea64b2c4eeef" title="3-2 核函数"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3-2 核函数</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80858e13e766c5f0050f" data-id="3b8e64bde40f80858e13e766c5f0050f"><span><div id="3b8e64bde40f80858e13e766c5f0050f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80858e13e766c5f0050f" title="什么是核函数"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">什么是核函数</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80fcabdbe7341ef3bfd7"><li><span class="notion-red"><b>核函数（Kernel Function）</b></span>是 Ascend C 算子 Device 侧的入口。Ascend C 通过扩展 C/C++ 函数语法来管理设备侧运行代码，开发者在核函数中实现算子逻辑，例如定义算子类及其成员函数来完成数据搬运与计算。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b8a2a9f89a76e55448"><li>核函数是 <span class="notion-red"><b>Host 侧和 Device 侧之间的重要桥梁</b></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a89379f919dc04191b"><li>典型形式：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a89379f919dc04191b"></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80c5b8aec0a062ae84e0"><li>与 CUDA 的典型写法相比：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80c5b8aec0a062ae84e0"></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b69656e1e8a29bf353"><li>核函数直接在设备侧执行。SPMD 编程模型允许核函数启动后，由多个计算核心并行执行同一份代码并处理不同数据。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f808f8bd6e7de5f017df6" data-id="3b8e64bde40f808f8bd6e7de5f017df6"><span><div id="3b8e64bde40f808f8bd6e7de5f017df6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f808f8bd6e7de5f017df6" title="函数类型限定符"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">函数类型限定符</span></span></h4><table class="notion-simple-table notion-block-3b8e64bde40f80b79fd3d8e5b14676b6"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3b8e64bde40f800b86afdd1841ed9856"><td class="" style="width:176.75px"><div class="notion-simple-table-cell">函数类型限定符</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">执行位置</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">调用方式</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">备注</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f8043bc57dfb68e857992"><td class="" style="width:176.75px"><div class="notion-simple-table-cell"><code class="notion-inline-code">__global__</code></div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">设备侧</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">由 <code class="notion-inline-code">&lt;&lt;&lt;...&gt;&gt;&gt;</code> 调用</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">必须为 <code class="notion-inline-code">void</code> 返回类型</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80c191a7f22c59b96fbd"><td class="" style="width:176.75px"><div class="notion-simple-table-cell"><code class="notion-inline-code">__aicore__</code></div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">设备侧</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">仅从设备端调用</div></td><td class="" style="width:176.75px"><div class="notion-simple-table-cell">表示在 AI Core 上执行</div></td></tr></tbody></table><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80efb4a3c0e24cf60527"><li>因此，Ascend C 核函数通常同时使用 <code class="notion-inline-code">__global__</code> 和 <code class="notion-inline-code">__aicore__</code>：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80efb4a3c0e24cf60527"></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80ceb837fa06d0c460fc" data-id="3b8e64bde40f80ceb837fa06d0c460fc"><span><div id="3b8e64bde40f80ceb837fa06d0c460fc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80ceb837fa06d0c460fc" title="变量类型限定符"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">变量类型限定符</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f803d85cadced724eca4f"><li>为了统一指针入参类型，可以使用：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f803d85cadced724eca4f"></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f800b86b5f1f1d05a768d"><li><code class="notion-inline-code">__gm__</code> 表示该指针变量指向 Global Memory 中的某一内存地址。</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f800b86b5f1f1d05a768d"><table class="notion-simple-table notion-block-3b8e64bde40f80ccafdfde348cc514e9"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3b8e64bde40f80a8a0a4cf003feaac1a"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">变量类型限定符</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">内存空间</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">含义</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80fa88f8d7d9a16e79ab"><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell"><code class="notion-inline-code">__gm__</code></div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">Global Memory</div></td><td class="" style="width:213.66666666666666px"><div class="notion-simple-table-cell">表明该指针变量指向 Global Memory 上某处内存地址</div></td></tr></tbody></table></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f808c9688e1c2ee9581a3"><li>常用宏：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f808c9688e1c2ee9581a3"></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8058a912c37da7e929d5"><li>核函数入参规则/建议：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8058a912c37da7e929d5"><ol start="1" class="notion-list notion-list-numbered notion-block-3b8e64bde40f8026b4dad61ce69ca8f1" style="list-style-type:decimal"><li>核函数必须具有 <code class="notion-inline-code">void</code> 返回类型。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3b8e64bde40f8067a5e5c8bf9877c6f2" style="list-style-type:decimal"><li>入参支持指针类型或 C/C++ 内置基础数据类型，例如 <code class="notion-inline-code">half*</code>、<code class="notion-inline-code">float*</code>、<code class="notion-inline-code">int32_t</code> 等。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3b8e64bde40f803b9bfacabef2b66e19" style="list-style-type:decimal"><li>可以使用 <code class="notion-inline-code">GM_ADDR</code> 统一封装 Global Memory 指针，避免函数入参列表过长。</li></ol></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f801da4a6d5567d9fcf52" data-id="3b8e64bde40f801da4a6d5567d9fcf52"><span><div id="3b8e64bde40f801da4a6d5567d9fcf52" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f801da4a6d5567d9fcf52" title="如何调用核函数"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">如何调用核函数</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f805d89f3ddcf81cdf350"><li>普通 C/C++ 函数调用：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f805d89f3ddcf81cdf350"></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8037a4c6ef0fd4c65f25"><li>Ascend C 核函数使用内核调用符：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8037a4c6ef0fd4c65f25"></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a395dcea5b89a647e4"><li>其中：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a395dcea5b89a647e4"><li><code class="notion-inline-code">blockDim</code>：规定核函数在多少个核上执行。每个核会被分配一个逻辑 ID <code class="notion-inline-code">block_idx</code>，编号从 0 开始；算子实现中可使用 <code class="notion-inline-code">GetBlockIdx()</code> 获取当前逻辑核 ID。</li><li><code class="notion-inline-code">stream</code>：类型为 <code class="notion-inline-code">aclrtStream</code>，表示任务队列，应用程序通过 stream 管理任务并行。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b188d2ffb5ed013982"><li>核函数调用是<span class="notion-red"><b>异步、非阻塞</b></span>的。Host 侧发起核函数后不会默认等待其立即结束，需要在需要结果或保证执行完成的位置显式同步，例如调用 <code class="notion-inline-code">aclrtSynchronizeStream(stream)</code>。</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80b188d2ffb5ed013982"><blockquote class="notion-quote notion-block-3b8e64bde40f80b0be51eaaee135c350"><div>内核调用符 <code class="notion-inline-code">&lt;&lt;&lt;...&gt;&gt;&gt;</code> 只在<span class="notion-red"><b> NPU 模式编译时使用</b></span>；CPU 模式下不能直接识别这一调用符号。</div></blockquote></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f80828185e94d066f0367" data-id="3b8e64bde40f80828185e94d066f0367"><span><div id="3b8e64bde40f80828185e94d066f0367" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80828185e94d066f0367" title="3-3Hello World"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3-3Hello World</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80fc8c42c17a45dad38d" data-id="3b8e64bde40f80fc8c42c17a45dad38d"><span><div id="3b8e64bde40f80fc8c42c17a45dad38d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80fc8c42c17a45dad38d" title="Device 侧核函数实现"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Device 侧核函数实现</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f804e8fe0dc5bd73b348c"><li>一个最小的 Hello World 核函数可以写成：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f804e8fe0dc5bd73b348c"></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a7ac09c94e9a7bd725"><li>这段代码包含三个关键部分：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80a7ac09c94e9a7bd725"><li><span class="notion-red"><b>核函数定义</b></span>：<code class="notion-inline-code">hello_world</code> 通过 <code class="notion-inline-code">__global__ __aicore__</code> 声明为 AI Core 核函数。</li><li><span class="notion-red"><b>核函数实现</b></span>：使用 <code class="notion-inline-code">PRINTF</code> 在核函数中输出信息。</li><li><span class="notion-red"><b>核函数调用封装</b></span>：<code class="notion-inline-code">hello_world_do</code> 使用 <code class="notion-inline-code">&lt;&lt;&lt;blockDim, nullptr, stream&gt;&gt;&gt;</code> 拉起核函数。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80158a2efc7ad7c2468a" data-id="3b8e64bde40f80158a2efc7ad7c2468a"><span><div id="3b8e64bde40f80158a2efc7ad7c2468a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80158a2efc7ad7c2468a" title="Host 侧调用流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Host 侧调用流程</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80e4876cdea6f7375889"><li>Host 侧需要先完成 AscendCL 初始化和运行资源创建，再调用核函数：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80e4876cdea6f7375889"></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80c19a37c1d6bcae8c88"><li>常见 AscendCL 接口及其作用：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80c19a37c1d6bcae8c88"><table class="notion-simple-table notion-block-3b8e64bde40f8050b53cfcd5772572b7"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3b8e64bde40f80e08f89eb9f3bc67396"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">接口</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">作用</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80b68797fce8c649d183"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">aclInit</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">AscendCL 初始化</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f8002b913c9ef9946d30e"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">aclrtSetDevice</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">指定目标 Device</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f800a9b5ac4fcc06f9911"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">aclrtCreateContext</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">创建运行上下文</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f8031b3c9ced8ef8c3a16"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">aclrtCreateStream</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">创建任务流</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f807794c1ca6844c99753"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">aclrtMallocHost</code> / <code class="notion-inline-code">aclrtMalloc</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">申请 Host/Device 内存</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f801a8ebec838674d9252"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">aclrtMemcpy</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">Host 与 Device 之间进行数据传输</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80aeb60cc604093dbeb7"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">&lt;&lt;&lt;...&gt;&gt;&gt;</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">启动 Device 核函数</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80dca260da0446004ecf"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">aclrtSynchronizeStream</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">等待指定 stream 中任务执行完成</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f805d9989dbcd2cd3d0a9"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">aclrtFree</code> / <code class="notion-inline-code">aclrtFreeHost</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">释放 Device/Host 内存</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80d09ab4f748ffba47eb"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">aclrtDestroyStream</code> / <code class="notion-inline-code">aclrtDestroyContext</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">释放运行管理资源</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f8018bc97c800484af347"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">aclrtResetDevice</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">复位 Device</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80409e55c8ad6b34ab69"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">aclFinalize</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">AscendCL 去初始化</div></td></tr></tbody></table></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8028ad57cebb1ac6c196"><li>完整调用链可以记为：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8028ad57cebb1ac6c196"></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f801cb88bc5411da7b1e0" data-id="3b8e64bde40f801cb88bc5411da7b1e0"><span><div id="3b8e64bde40f801cb88bc5411da7b1e0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f801cb88bc5411da7b1e0" title="3-4 完整核函数范讲"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3-4 完整核函数范讲</span></span></h3><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8099a6fafebc5852d4bf"><li>一个完整的向量计算核函数通常不会把所有逻辑堆在一个函数中，而是按照 Ascend C 流水编程范式拆分为多个阶段。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f807483b9ec08659b0a81" data-id="3b8e64bde40f807483b9ec08659b0a81"><span><div id="3b8e64bde40f807483b9ec08659b0a81" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f807483b9ec08659b0a81" title="典型代码结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">典型代码结构</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f801f941ce6f36c0d1878"><li>各函数职责：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f801f941ce6f36c0d1878"><li><code class="notion-inline-code">Init</code>：完成 GlobalTensor 地址绑定、Pipe/Queue/Buffer 等资源初始化。</li><li><code class="notion-inline-code">Process</code>：组织循环，按 Tile 依次调度 <code class="notion-inline-code">CopyIn → Compute → CopyOut</code>。</li><li><code class="notion-inline-code">CopyIn</code>：从 Global Memory 获取输入数据，放入本地 Tensor，并通过队列入队。</li><li><code class="notion-inline-code">Compute</code>：从输入队列出队，在 Local Memory 上执行向量/矩阵计算，结果放入输出队列。</li><li><code class="notion-inline-code">CopyOut</code>：从输出队列出队，将结果写回 Global Memory，并释放本地 Tensor。</li></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80c8ac86d2847bd412f4" data-id="3b8e64bde40f80c8ac86d2847bd412f4"><span><div id="3b8e64bde40f80c8ac86d2847bd412f4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80c8ac86d2847bd412f4" title="TPIPE 流水编程模型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">TPIPE 流水编程模型</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f800dbd26f22e2690bd40"><li>Ascend C 的 TPIPE 流水编程以“搬入、计算、搬出”为三个主要 Stage：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f800dbd26f22e2690bd40"></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8007bba3e4f4d8d04933"><li>不同 Tile 可以在流水线上交错运行，例如当第 0 块数据正在 <code class="notion-inline-code">Compute</code> 时，第 1 块数据可以 <code class="notion-inline-code">CopyIn</code>，而前一块数据可以继续 <code class="notion-inline-code">CopyOut</code>。这种重叠执行能提高搬运单元与计算单元的利用率。</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3b8e64bde40f80b2a7e0e55bc950c685"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3A876d43e7-0118-4839-9cc2-d4adb75dfac8%3A%E5%AE%8C%E6%95%B4%E5%90%91%E9%87%8F%E6%A0%B8%E5%87%BD%E6%95%B0%E4%B8%AD%E7%9A%84_CopyIn-Compute-CopyOut_%E6%B5%81%E6%B0%B4.png?table=block&amp;id=3b8e64bd-e40f-80b2-a7e0-e55bc950c685&amp;t=3b8e64bd-e40f-80b2-a7e0-e55bc950c685" alt="完整向量核函数中的 CopyIn/Compute/CopyOut 流水" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">完整向量核函数中的 CopyIn/Compute/CopyOut 流水</figcaption></div></figure><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3b8e64bde40f8046b8d5e40adf4c22e7" data-id="3b8e64bde40f8046b8d5e40adf4c22e7"><span><div id="3b8e64bde40f8046b8d5e40adf4c22e7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f8046b8d5e40adf4c22e7" title="4-算子开发环境搭建"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4-算子开发环境搭建</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f80b7a597e29bd011aa80" data-id="3b8e64bde40f80b7a597e29bd011aa80"><span><div id="3b8e64bde40f80b7a597e29bd011aa80" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80b7a597e29bd011aa80" title="4-1 环境部署概述"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4-1 环境部署概述</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f80788345cc192744c591" data-id="3b8e64bde40f80788345cc192744c591"><span><div id="3b8e64bde40f80788345cc192744c591" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80788345cc192744c591" title="开发环境与运行环境"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">开发环境与运行环境</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8033bd69edfc6c938b4e"><li><span class="notion-red"><b>开发环境</b></span>主要用于代码开发、编译、调测等活动，存在两类常见场景：</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8033bd69edfc6c938b4e"><li><span class="notion-red"><b>场景一：在非昇腾 AI 设备上安装开发环境</b></span><b>。</b></li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80048ee6d6e51737a929"><li>可用于代码开发、编译等不依赖昇腾设备的活动。</li><li>例如 ATC 模型转换、算子和推理应用程序的纯代码开发。</li></ul><li><span class="notion-red"><b>场景二：在昇腾 AI 设备上安装开发环境</b></span><b>。</b></li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80da9b8ad896acefc141"><li>支持代码开发和编译。</li><li>同时可以运行应用程序，或进行训练脚本的迁移、开发与调试。</li></ul></ul></ul><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f80d3a508eb4c890ac496"><li><span class="notion-red"><b>运行环境</b></span>部署在昇腾 AI 设备上，用于运行开发完成的应用程序，或者进行训练脚本的迁移、开发与调试。</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3b8e64bde40f80f18980d94117c4b52b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3Af4d0c4fb-600b-460c-88d2-2d7d3e2e722e%3ACANN_%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E4%B8%8E%E8%BF%90%E8%A1%8C%E7%8E%AF%E5%A2%83%E9%83%A8%E7%BD%B2%E6%B5%81%E7%A8%8B.png?table=block&amp;id=3b8e64bd-e40f-80f1-8980-d94117c4b52b&amp;t=3b8e64bd-e40f-80f1-8980-d94117c4b52b" alt="CANN 开发环境与运行环境部署流程" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">CANN 开发环境与运行环境部署流程</figcaption></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3b8e64bde40f809695a9fb5ddd2874fe" data-id="3b8e64bde40f809695a9fb5ddd2874fe"><span><div id="3b8e64bde40f809695a9fb5ddd2874fe" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f809695a9fb5ddd2874fe" title="CANN 相关安装包"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">CANN 相关安装包</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8018a639fb3de26f4be0"><li>在昇腾社区中可以从“产品 → CANN”获取相关安装包。社区版更新频率较高，适合开发者使用。</li><ul class="notion-list notion-list-disc notion-block-3b8e64bde40f8018a639fb3de26f4be0"><table class="notion-simple-table notion-block-3b8e64bde40f8027abf5c3233558c10e"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3b8e64bde40f805cb4dad7ac5749579e"><td class="" style="width:320.5px"><div class="notion-simple-table-cell">软件包名称（示例版本）</div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">说明</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80319899ec988c9b9217"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-nnrt_8.0.RC2.alpha002_linux-x86_64.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">x86 平台推理引擎软件包，适用于命令行方式安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f800e8b24f662332e6aa2"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-amct_8.0.RC2.alpha002_linux-aarch64.tar.gz</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">ARM 平台模型小型化工具，适用于命令行方式安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80cca4c0d023c34754a2"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-amct_8.0.RC2.alpha002_linux-x86_64.tar.gz</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">x86 平台模型小型化工具，适用于命令行方式安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f806fafb2e22572cca863"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-communitysdk_8.0.RC2.alpha002_linux-aarch64.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">CANN 社区算子开发工具包，适用于命令行安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f806e884ccac00d6449fc"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-communitysdk_8.0.RC2.alpha002_linux-x86_64.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">CANN 社区算子开发工具包，适用于命令行安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f802daca0eca70883d71a"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-robotmiddleware_8.0.RC2.alpha002_linux-aarch64.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">机器人应用开发中间件 OpenHiva 软件包，适用于命令行安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80cc8e08c3c0a0cfbce1"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-toolkit_8.0.RC2.alpha002_linux-aarch64.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">ARM 平台开发套件软件包，适用于命令行安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f806fb296eab5586c0342"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-toolkit_8.0.RC2.alpha002_linux-x86_64.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">x86 平台开发套件软件包，适用于命令行安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f8094a030dd2d7e87237a"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-kernels-310p_8.0.RC2.alpha002_linux.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">CANN 算子二进制安装包，适用于命令行安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80699415c099ab6fdf30"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-kernels-310b_8.0.RC2.alpha002_linux.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">CANN 算子二进制安装包，适用于命令行安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80889a96ecc3554e5a0c"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-kernels-910_8.0.RC2.alpha002_linux.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">CANN 算子二进制安装包，适用于命令行安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80049688e993388ebdf0"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-kernels-910b_8.0.RC2.alpha002_linux.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">CANN 算子二进制安装包，适用于命令行安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80958aa4f053541dfb34"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-nnae_8.0.RC2.alpha002_linux-aarch64.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">ARM 平台深度学习引擎软件包，适用于命令行方式安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f8091acc7dddf8171f85f"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-nnae_8.0.RC2.alpha002_linux-x86_64.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">x86 平台深度学习引擎软件包，适用于命令行方式安装场景</div></td></tr><tr class="notion-simple-table-row notion-block-3b8e64bde40f80a0a359d07db34b8755"><td class="" style="width:320.5px"><div class="notion-simple-table-cell"><code class="notion-inline-code">Ascend-cann-nnrt_8.0.RC2.alpha002_linux-aarch64.run</code></div></td><td class="" style="width:320.5px"><div class="notion-simple-table-cell">ARM 平台推理引擎软件包，适用于命令行方式安装场景</div></td></tr></tbody></table></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f80d388f5c8690d7d830a" data-id="3b8e64bde40f80d388f5c8690d7d830a"><span><div id="3b8e64bde40f80d388f5c8690d7d830a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80d388f5c8690d7d830a" title="4.2 在 CPU 上部署开发环境"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.2 在 CPU 上部署开发环境</span></span></h3><div class="notion-row"><a class="notion-bookmark notion-block-3b8e64bde40f80b498c4c8770d9759fd" href="https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/latest/softwareinst/instg/instg_0000.html?OS=Ubuntu&amp;InstallType=netdocker" target="_blank" rel="noopener noreferrer"><div><div class="notion-bookmark-title">选择安装场景-软件安装-发行与安装-CANN9.1.0开发文档-昇腾社区</div><div class="notion-bookmark-description">&lt;!DOCTYPE html&gt; 选择安装场景 本文档提供了详细的NPU驱动和固件、CANN软件安装步骤，若您初次上手或希望快速安装CANN，建议参考《CANN 快速安装》进行部署。 在CANN快速安装中，稳定版本为核心功能完善，稳定性较高的版本，Weekly版本为提供新特性，供开发者提前试用的版本。请您根据需求进行选择。 条件名称 条件名称-解释 条件名称-属性 条件名称-取值 条件取值-ID I</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fwww.hiascend.com%2F_static3%2Ffavicon.ico?table=block&amp;id=3b8e64bd-e40f-80b4-98c4-c8770d9759fd&amp;t=3b8e64bd-e40f-80b4-98c4-c8770d9759fd" alt="选择安装场景-软件安装-发行与安装-CANN9.1.0开发文档-昇腾社区" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/latest/softwareinst/instg/instg_0000.html?OS=Ubuntu&amp;InstallType=netdocker</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fwww.hiascend.com%2F_static3%2Flogo.BmJjMz5z.png?table=block&amp;id=3b8e64bd-e40f-80b4-98c4-c8770d9759fd&amp;t=3b8e64bd-e40f-80b4-98c4-c8770d9759fd" alt="选择安装场景-软件安装-发行与安装-CANN9.1.0开发文档-昇腾社区" loading="lazy" decoding="async"/></div></a></div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f809d8abfee2dada06f8e" data-id="3b8e64bde40f809d8abfee2dada06f8e"><span><div id="3b8e64bde40f809d8abfee2dada06f8e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f809d8abfee2dada06f8e" title="4.3 在香橙派上部署开发及运行环境"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.3 在香橙派上部署开发及运行环境</span></span></h3><div class="notion-row"><a class="notion-bookmark notion-block-3b8e64bde40f800aac6fcf95fd7fab99" href="https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/latest/softwareinst/instg/instg_0000.html?OS=Ubuntu&amp;InstallType=localpack" target="_blank" rel="noopener noreferrer"><div><div class="notion-bookmark-title">选择安装场景-软件安装-发行与安装-CANN9.1.0开发文档-昇腾社区</div><div class="notion-bookmark-description">&lt;!DOCTYPE html&gt; 选择安装场景 本文档提供了详细的NPU驱动和固件、CANN软件安装步骤，若您初次上手或希望快速安装CANN，建议参考《CANN 快速安装》进行部署。 在CANN快速安装中，稳定版本为核心功能完善，稳定性较高的版本，Weekly版本为提供新特性，供开发者提前试用的版本。请您根据需求进行选择。 条件名称 条件名称-解释 条件名称-属性 条件名称-取值 条件取值-ID I</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fwww.hiascend.com%2F_static3%2Ffavicon.ico?table=block&amp;id=3b8e64bd-e40f-800a-ac6f-cf95fd7fab99&amp;t=3b8e64bd-e40f-800a-ac6f-cf95fd7fab99" alt="选择安装场景-软件安装-发行与安装-CANN9.1.0开发文档-昇腾社区" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/latest/softwareinst/instg/instg_0000.html?OS=Ubuntu&amp;InstallType=localpack</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fwww.hiascend.com%2F_static3%2Flogo.BmJjMz5z.png?table=block&amp;id=3b8e64bd-e40f-800a-ac6f-cf95fd7fab99&amp;t=3b8e64bd-e40f-800a-ac6f-cf95fd7fab99" alt="选择安装场景-软件安装-发行与安装-CANN9.1.0开发文档-昇腾社区" loading="lazy" decoding="async"/></div></a></div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3b8e64bde40f80388570ce0a17290702" data-id="3b8e64bde40f80388570ce0a17290702"><span><div id="3b8e64bde40f80388570ce0a17290702" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b8e64bde40f80388570ce0a17290702" title="4.4 在华为云 ModelArts 上部署开发&amp;运行环境"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.4 在华为云 ModelArts 上部署开发&amp;运行环境</span></span></h3><div class="notion-row"><a class="notion-bookmark notion-block-3b8e64bde40f80c49a52f301c5281030" href="https://gitcode.com/org/cann/cannlab/environment" target="_blank" rel="noopener noreferrer"><div><div class="notion-bookmark-title">CANNLab - 我的环境 - 开源代码托管,代码协作 - AtomGit</div><div class="notion-bookmark-description">CANNLab 是为 CANN 社区开发者提供的开箱即用的云端开发环境，内置 CANN 软件、NPU 算力和 WebIDE 等全套开发工具提供浏览器和本地 IDE 客户端双接入方式，支撑社区开发者算子开发、模型训&amp;调优和 AI 应用开发三大领域的开发活动。</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fcdn-static.gitcode.com%2Fstatic%2Fimages%2Flogo-favicon.png?table=block&amp;id=3b8e64bd-e40f-80c4-9a52-f301c5281030&amp;t=3b8e64bd-e40f-80c4-9a52-f301c5281030" alt="CANNLab - 我的环境 - 开源代码托管,代码协作 - AtomGit" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://gitcode.com/org/cann/cannlab/environment</div></div></div></a></div><div class="notion-blank notion-block-3b8e64bde40f80739219d1d4eede55f3"> </div></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[神经网络与深度学习笔记_Day7]]></title>
            <link>http://blog.zzhow.com/article/NN-DL-Learning7</link>
            <guid>http://blog.zzhow.com/article/NN-DL-Learning7</guid>
            <pubDate>Tue, 17 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[神经网络与深度学习笔记_Day7，包含 CNN图像分类案例、RNN介绍、词嵌入层、循环网络层 与 AI歌词生成器案例]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-2ece64bde40f80d89b9efe19bbf93881"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-sync-block notion-block-3b0e64bde40f80e08266c26776d7e106"><div class="notion-text notion-block-305e64bde40f80b283a7ca26d942404d">@ZZHow(ZZHow1024)</div><div class="notion-text notion-block-305e64bde40f80608ef1ff3c55c357fa">参考课程：</div><div class="notion-text notion-block-305e64bde40f80908188e44d660c934d">【<b>黑马程序员AI大模型《神经网络与深度学习》全套视频课程，涵盖Pytorch深度学习框架、BP神经网络、CNN图像分类算法及RNN文本生成算法</b>】</div><div class="notion-text notion-block-305e64bde40f8054a0fcce29d495d27f">[<b><a class="notion-link" href="https://www.bilibili.com/video/BV1c5yrBcEEX" target="_blank" rel="noopener noreferrer">https://www.bilibili.com/video/BV1c5yrBcEEX</a></b>]</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-305e64bde40f80f39c60f2ad829c306d" data-id="305e64bde40f80f39c60f2ad829c306d"><span><div id="305e64bde40f80f39c60f2ad829c306d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#305e64bde40f80f39c60f2ad829c306d" title="01_今日内容大纲介绍"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">01_今日内容大纲介绍</span></span></h2><ul class="notion-list notion-list-disc notion-block-305e64bde40f806d8eebfe2cb9474599"><li>CNN 图像分类案例</li><ul class="notion-list notion-list-disc notion-block-305e64bde40f806d8eebfe2cb9474599"><li>加载数据集 → CIFAR10 数据集</li><li>构建神经网络分类模型</li><li>模型训练</li><li>模型评估</li><li>模型优化</li></ul></ul><ul class="notion-list notion-list-disc notion-block-305e64bde40f802a91f3c8f08b98fb83"><li>RNN 入门</li><ul class="notion-list notion-list-disc notion-block-305e64bde40f802a91f3c8f08b98fb83"><li>生成杰伦歌词案例</li></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-305e64bde40f809c83b8e2a50243e899" data-id="305e64bde40f809c83b8e2a50243e899"><span><div id="305e64bde40f809c83b8e2a50243e899" class="notion-header-anchor"></div><a class="notion-hash-link" href="#305e64bde40f809c83b8e2a50243e899" title="02_CNN图像分类案例_准备数据集"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">02_CNN图像分类案例_准备数据集</span></span></h2><ul class="notion-list notion-list-disc notion-block-305e64bde40f8084948ee1ee67e07c69"><li>卷积神经网络案例</li><ul class="notion-list notion-list-disc notion-block-305e64bde40f8084948ee1ee67e07c69"><li>使用前面学习到的知识来构建一个卷积神经网络，并训练该网络实现图像分类。要完成这个案例，需要学习的内容如下：</li><ul class="notion-list notion-list-disc notion-block-305e64bde40f80d2984fc0c838521726"><li>了解 CIFAR10 数据集</li><li>搭建卷积神经网络</li><li>编写训练函数</li><li>编写预测函数</li></ul></ul></ul><ul class="notion-list notion-list-disc notion-block-305e64bde40f801c9db7fcbdc7f136f3"><li>CIFAR10 数据集：有 5 万张训练图像、1 万张测试图像、10 个类别、每个类别有 6k 个图像，图像大小 32×32×3。下图列举了 10 个类，每一类随机展示了 10 张图片。</li></ul><ul class="notion-list notion-list-disc notion-block-305e64bde40f80cca89ee39ff8077584"><li>案例演示：<b><a class="notion-link" href="https://github.com/ZZHow1024/NN-DL-Learning/blob/main/Day07/01_cnn_image_classification.py" target="_blank" rel="noopener noreferrer">01_cnn_image_classification.py</a></b>（CNN案例_图像分类）</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-305e64bde40f80de8dc2d6f9e8fd4de7" data-id="305e64bde40f80de8dc2d6f9e8fd4de7"><span><div id="305e64bde40f80de8dc2d6f9e8fd4de7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#305e64bde40f80de8dc2d6f9e8fd4de7" title="03_CNN图像分类案例_搭建神经网络_思路分析"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">03_CNN图像分类案例_搭建神经网络_思路分析</span></span></h2><ul class="notion-list notion-list-disc notion-block-305e64bde40f808bbff2e900feb52537"><li>搭建图像分类网络</li><ul class="notion-list notion-list-disc notion-block-305e64bde40f808bbff2e900feb52537"><li>网络结构</li><ul class="notion-list notion-list-disc notion-block-305e64bde40f80d599f9d36bd4b322df"><ol start="1" class="notion-list notion-list-numbered notion-block-305e64bde40f80018fd9ea230f4fd0c3" style="list-style-type:decimal"><li>输入形状：32×32。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-305e64bde40f800ca2d3f1abeefcd988" style="list-style-type:decimal"><li>第一个卷积层输入 3 个 Channel，输出 6 个 Channel，Kernel Size 为 3×3。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-305e64bde40f807ab93ff0081983f8d4" style="list-style-type:decimal"><li>第一个池化层输入 30×30，输出 15×15，Kernel Size 为 2×2，Stride 为 2。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-305e64bde40f805f9df2c581ce98ab53" style="list-style-type:decimal"><li>第二个卷积层输入 6 个 Channel，输出 16 个 Channel，Kernel Size 为 3×3。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-305e64bde40f80ad8283d41d8ce0132c" style="list-style-type:decimal"><li>第二个池化层输入 13×13，输出 6×6，Kernel Size 为 2×2，Stride 为 2。</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-305e64bde40f80518947e6f830d88e86" style="list-style-type:decimal"><li>第一个全连接层输入 576 维，输出 120 维。</li></ol><ol start="7" class="notion-list notion-list-numbered notion-block-305e64bde40f80a88582f8eb030d4c89" style="list-style-type:decimal"><li>第二个全连接层输入 120 维，输出 84 维。</li></ol><ol start="8" class="notion-list notion-list-numbered notion-block-305e64bde40f804aa593cdf3b16c3dbc" style="list-style-type:decimal"><li>最后的输出层输入 84 维，输出 10 维。</li></ol><ol start="9" class="notion-list notion-list-numbered notion-block-305e64bde40f8072a545edcdc7cb5f02" style="list-style-type:decimal"><li>在每个卷积计算之后应用 ReLU 激活函数来给网络增加非线性因素。</li></ol></ul><li>网络结构图</li><ul class="notion-list notion-list-disc notion-block-305e64bde40f806aa6fbcaf36f4c90af"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-305e64bde40f8024beeeffbb8836e7e1"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3A0040b003-c2b4-48db-8e37-ab93b8c7b66c%3A%E7%BD%91%E7%BB%9C%E7%BB%93%E6%9E%84%E5%9B%BE.png?table=block&amp;id=305e64bd-e40f-8024-beee-ffbb8836e7e1&amp;t=305e64bd-e40f-8024-beee-ffbb8836e7e1" alt="网络结构图" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">网络结构图</figcaption></div></figure></ul></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-305e64bde40f806196e9c04872d2438c" data-id="305e64bde40f806196e9c04872d2438c"><span><div id="305e64bde40f806196e9c04872d2438c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#305e64bde40f806196e9c04872d2438c" title="04_CNN图像分类案例_搭建神经网络_代码实现"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">04_CNN图像分类案例_搭建神经网络_代码实现</span></span></h2><ul class="notion-list notion-list-disc notion-block-306e64bde40f80808117d2762480d809"><li>卷积层参数计算公式：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></li></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f802294a6d25ea5bab8c5"><li>代码</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f802294a6d25ea5bab8c5"></ul></ul><ul class="notion-list notion-list-disc notion-block-305e64bde40f8005b927e63460349cc5"><li>案例演示：<b><a class="notion-link" href="https://github.com/ZZHow1024/NN-DL-Learning/blob/main/Day07/01_cnn_image_classification.py" target="_blank" rel="noopener noreferrer">01_cnn_image_classification.py</a></b>（CNN案例_图像分类）</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-305e64bde40f8086b807e675ea702549" data-id="305e64bde40f8086b807e675ea702549"><span><div id="305e64bde40f8086b807e675ea702549" class="notion-header-anchor"></div><a class="notion-hash-link" href="#305e64bde40f8086b807e675ea702549" title="05_CNN图像分类案例_模型训练"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">05_CNN图像分类案例_模型训练</span></span></h2><ul class="notion-list notion-list-disc notion-block-306e64bde40f80c0a0d3c03c4d038f8d"><li>代码</li><ul class="notion-list notion-list-disc notion-block-306e64bde40f80c0a0d3c03c4d038f8d"></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80a9aef4f61b44fc4197"><li>案例演示：<b><a class="notion-link" href="https://github.com/ZZHow1024/NN-DL-Learning/blob/main/Day07/01_cnn_image_classification.py" target="_blank" rel="noopener noreferrer">01_cnn_image_classification.py</a></b>（CNN案例_图像分类）</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-305e64bde40f803d955acb95f33aeda7" data-id="305e64bde40f803d955acb95f33aeda7"><span><div id="305e64bde40f803d955acb95f33aeda7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#305e64bde40f803d955acb95f33aeda7" title="06_CNN图像分类案例_模型测试"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">06_CNN图像分类案例_模型测试</span></span></h2><ul class="notion-list notion-list-disc notion-block-30ae64bde40f8086a531c03c0f71acb3"><li>代码</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f8086a531c03c0f71acb3"></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80dfb92bc18eef63d202"><li>案例演示：<b><a class="notion-link" href="https://github.com/ZZHow1024/NN-DL-Learning/blob/main/Day07/01_cnn_image_classification.py" target="_blank" rel="noopener noreferrer">01_cnn_image_classification.py</a></b>（CNN案例_图像分类）</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-305e64bde40f806d89efefdd50144bc7" data-id="305e64bde40f806d89efefdd50144bc7"><span><div id="305e64bde40f806d89efefdd50144bc7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#305e64bde40f806d89efefdd50144bc7" title="07_CNN图像分类案例_优化及总结"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">07_CNN图像分类案例_优化及总结</span></span></h2><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80979068f5810c7cb91b"><li>掌握模型构建流程</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80979068f5810c7cb91b"><li>加载数据集</li><li>模型构建</li><li>模型训练</li><li>模型测试</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80c09692eee96d1fb490"><li>优化方法</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80c09692eee96d1fb490"><li>增加卷积核输出通道数</li><li>增加全连接层的参数量</li><li>调整学习率</li><li>调整优化方法</li><li>修改激活函数</li><li>…</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80289633fc5fc284f047"><li><b><a class="notion-link" href="https://github.com/ZZHow1024/NN-DL-Learning/blob/main/Day07/02_cnn_image_classification_optimized.py" target="_blank" rel="noopener noreferrer">02_cnn_image_classification_optimized.py</a></b>（CNN案例_图像分类_优化版）</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-30ae64bde40f80268e58fd200792b9ff" data-id="30ae64bde40f80268e58fd200792b9ff"><span><div id="30ae64bde40f80268e58fd200792b9ff" class="notion-header-anchor"></div><a class="notion-hash-link" href="#30ae64bde40f80268e58fd200792b9ff" title="08_RNN介绍"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">08_RNN介绍</span></span></h2><ul class="notion-list notion-list-disc notion-block-30ae64bde40f809f9e05f7b736388f6c"><li>RNN 介绍</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f809f9e05f7b736388f6c"><li>循环神经网络（Recurrent Neural Network, RNN）是一种<span class="notion-red"><b>专门处理序列数据的神经网络</b></span>。与传统的前馈神经网络不同，RNN具有“循环”结构，能够处理和记住前面时间步的信息，使其特别适用于时间序列数据或有时序依赖的任务。</li><li>需要明确什么是<span class="notion-red"><b>序列数据</b></span>，时间序列数据是指在不同时间点上收集到的数据，这类数据反映了某一事物、现象等随时间的变化状态或程度。这是时间序列数据的定义，当然这里也可以不是时间，比如文字序列，但总归序列数据有一个特点——<span class="notion-red"><b>后面的数据跟前面的数据有关系</b></span>。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f800e9391dab8128c75cf"><li>RNN 的应用</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f800e9391dab8128c75cf"><li>自然语言处理（NLP）：文本生成、语言建模、机器翻译、情感分析等。</li><li>时间序列预测：股市预测、气象预测、传感器数据分析等。</li><li>语音识别：将语音信号转换为文字。</li><li>音乐生成：通过学习音乐的时序模式来生成新乐曲。
</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80eb9573cb771e5446e4"><li>自然语言处理概述</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80eb9573cb771e5446e4"><li>自然语言处理（Nature Language Processing, NLP）研究的主要是通过计算机算法来理解自然语言。对于自然语言来说，处理的数据主要就是人类的语言，例如：汉语、英语、法语等，该类型的数据不像我们前面接触过的结构化数据、或者图像数据可以很方便的进行数值化。</li></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-30ae64bde40f80d58128d34f2c19de59" data-id="30ae64bde40f80d58128d34f2c19de59"><span><div id="30ae64bde40f80d58128d34f2c19de59" class="notion-header-anchor"></div><a class="notion-hash-link" href="#30ae64bde40f80d58128d34f2c19de59" title="09_词嵌入层_解释"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">09_词嵌入层_解释</span></span></h2><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80ea9169c7eb37ca96bb"><li>词嵌入层作用</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80ea9169c7eb37ca96bb"><li><span class="notion-red"><b>词嵌入层的作用就是将文本转换为向量</b></span>。</li><li>词嵌入层在 RNN 中的作用有<span class="notion-red"><b>输入表示</b></span>、<span class="notion-red"><b>降低维度</b></span>和<span class="notion-red"><b>捕捉语义相似性</b></span>。</li><li>词嵌入层首先会根据输入的词的数量构建一个<span class="notion-red"><b>词向量矩阵</b></span>，例如: 我们有 100 个词，每个</li><li>希望转换成 128 维度的向量，那么构建的矩阵形状即为：100*128，输入的每个词都对应了一个该矩阵中的一个向量。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80fead86c2adb2aa77e8"><li>词嵌入层工作流程</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80fead86c2adb2aa77e8"><li><span class="notion-red"><b>初始化词向量</b></span>：词嵌入层的初始词向量通常会使用随机初始化或者通过加载预训练的词向量（如 Word2Vec 或 GloVe）进行初始化。</li><li><span class="notion-red"><b>输入索引</b></span>：每个单词在词汇表中都有一个唯一的索引。输入文本（例如一个句子）会先被分词，然后每个单词会被转换为相应的索引。</li><li><span class="notion-red"><b>查找词向量</b></span>：词嵌入层将这些单词索引映射为对应的词向量。这些词向量是一个低维稠密向量，表示该词的语义。</li><li><span class="notion-red"><b>输入到 RNN</b></span>：这些词向量作为 RNN 的输入，RNN 处理它们并根据上下文生成一个序列的输出。</li></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-30ae64bde40f80a78184c6b8eba6af03" data-id="30ae64bde40f80a78184c6b8eba6af03"><span><div id="30ae64bde40f80a78184c6b8eba6af03" class="notion-header-anchor"></div><a class="notion-hash-link" href="#30ae64bde40f80a78184c6b8eba6af03" title="10_词嵌入层_API演示"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10_词嵌入层_API演示</span></span></h2><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80b6851dfd0cab255d6d"><li>词嵌入层使用</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80b6851dfd0cab255d6d"><li>在 PyTorch 中，使用 <code class="notion-inline-code">nn.Embedding</code> 词嵌入层来实现输入词的向量化。</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80d19220e2c309b39d5b"></ul><li><code class="notion-inline-code">nn.Embedding</code> 对象构建时，最主要有两个参数</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f808ebba5dc490e0b3968"><li><code class="notion-inline-code">num_embeddings</code> 表示<span class="notion-red"><b>词的数量</b></span>。</li><li><code class="notion-inline-code">embedding_dim</code> 表示<span class="notion-red"><b>用多少维的向量来表示每个词</b></span>。</li></ul><li>将词转换为词向量的步骤</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f809c95a6cd67582d623d"><ol start="1" class="notion-list notion-list-numbered notion-block-30ae64bde40f8040935ce33005f0d242" style="list-style-type:decimal"><li>先将语料进行分词，构建词与索引的映射，我们可以把这个映射叫做词表，词表中每个词都对应了一个唯一的索引。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-30ae64bde40f8037aed1f798fc247a70" style="list-style-type:decimal"><li>然后使用 nn.Embedding 构建词嵌入矩阵，词索引对应的向量即为该词对应的数值化后的向量表示。</li></ol></ul></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80ffb9e9ed4c9b8adf67"><li><b><a class="notion-link" href="https://github.com/ZZHow1024/NN-DL-Learning/blob/main/Day07/03_word_embedding_demo.py" target="_blank" rel="noopener noreferrer">03_word_embedding_demo.py</a></b>（词嵌入层演示）</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-30ae64bde40f803fbeb8e56286d05fe9" data-id="30ae64bde40f803fbeb8e56286d05fe9"><span><div id="30ae64bde40f803fbeb8e56286d05fe9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#30ae64bde40f803fbeb8e56286d05fe9" title="11_RNN层(循环网络层)_简介"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11_RNN层(循环网络层)_简介</span></span></h2><ul class="notion-list notion-list-disc notion-block-30ae64bde40f800bae1bd9b1786a3fde"><li>文本数据是具有序列特性的</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f800bae1bd9b1786a3fde"><li>例如：“我爱你”，这串文本就是具有序列关系的，“爱”需要在“我”之后，“你”需要在“爱”之后，如果颠倒了顺序，那么可能就会表达不同的意思。</li><li>为了表示出数据的序列关系，需要使用循环神经网络 (Recurrent Nearal Networks, RNN) 来对数据进行建模，RNN 是一个作用于处理带有序列特点的样本数据。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80369255fd808a154c02"><li>RNN 计算过程</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80369255fd808a154c02"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-30ae64bde40f80e8ae6cd2322afe01ec"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/attachment%3Adb940c94-0d16-4232-9197-defef038542d%3ARNN%E8%AE%A1%E7%AE%97%E8%BF%87%E7%A8%8B.png?table=block&amp;id=30ae64bd-e40f-80e8-ae6c-d2322afe01ec&amp;t=30ae64bd-e40f-80e8-ae6c-d2322afe01ec" alt="RNN计算过程" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">RNN计算过程</figcaption></div></figure><li>h 表示隐藏状态，保存了<span class="notion-red"><b>序列数据中的历史信息</b></span>，并将这些信息传递给下一个时间步，从而允许 RNN 处理和预测序列数据中的元素。</li><li>每一次的输入包含两个值：上一个时间步的隐藏状态、当前状态的输入值 x。</li><li>每一次的输出也会包含两个值：当前时间步的隐藏状态、当前时间步的预测结果 y。</li><li>隐藏状态作用</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f801ba046e97f95ca4737"><ol start="1" class="notion-list notion-list-numbered notion-block-30ae64bde40f80dfb4d2c77081c58981" style="list-style-type:decimal"><li>记忆功能：隐藏状态就像 RNN 的记忆，它能够在不同的时间步之间传递信息。当一个新的输入进入网络时，当前的隐藏状态会结合这个新输入来生成新的隐藏状态。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-30ae64bde40f80a98be4dfbc179ea68e" style="list-style-type:decimal"><li>上下文理解：由于隐藏状态携带了过去的信息，它可以用于理解和生成与上下文相关的输出。这对于语言模型、机器翻译等任务尤其重要。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-30ae64bde40f807eb7bcd23309e9c80f" style="list-style-type:decimal"><li>连接不同时间步：隐藏状态通过网络内部的循环连接将各个时间步连接起来，使得网络可以处理变长的序列数据。</li></ol></ul><li>实际上只有一个神经元，“我爱你”三个字是重复输入到同一个神经元中。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f8076a370c79f9e0f310f"><li>RNN 神经元内部计算</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f8076a370c79f9e0f310f"><li><span class="notion-red"><b>计算隐藏状态</b></span>：每个时间步的隐藏状态 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是根据当前输入 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 和前一时刻的隐藏状态 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 计算的。</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80e89c92d508f5707e33"><li>公式：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></li></ul><li>上述公式中</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f806f8249f28a8dbec745"><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 表示输入数据的权重</li><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 表示输入数据的偏置</li><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 表示输入隐藏状态的权重</li><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 表示输入隐藏状态的偏置</li><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 表示输入隐藏状态</li><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 表示输出隐藏状态</li><li>最后对输出的结果使用 tanh 激活函数进行计算，得到该神经元你的输出隐藏状态。</li></ul><li><span class="notion-red"><b>计算当前时刻的输出</b></span>：网络的输出 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是当前时刻的隐藏状态经过一个线性变换得到的。</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80bd92c2c1952992f615"><li>公式：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></li></ul><li>上述公式中</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80958bcfd8a6eee50ce2"><ol start="1" class="notion-list notion-list-numbered notion-block-30ae64bde40f80bd8e2cca7c0954707e" style="list-style-type:decimal"><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是当前时刻的输出（通常是一个向量，表示当前时刻的预测值，RNN 层的预测值）</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-30ae64bde40f80a9bd62d17be391d991" style="list-style-type:decimal"><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是当前时刻的隐藏状态</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-30ae64bde40f800aa7bde8759e9f35a7" style="list-style-type:decimal"><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是从隐藏状态到输出的权重矩阵</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-30ae64bde40f80e397fbfea7c6fa68d8" style="list-style-type:decimal"><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是输出层的偏置项</li></ol></ul><li><span class="notion-red"><b>词汇表映射</b></span>：输出 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是一个<span class="notion-red"><b>向量</b></span>，该向量经过<span class="notion-red"><b>全连接层</b></span>后输出得到最终预测结果 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>，<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 中每个元素代表当前时刻生成词汇表中某个词的得分（或概率，通过激活函数如 Softmax）。<span class="notion-red"><b>词汇表有多少个词，Ypred 就有多少个元素值，最大元素值对应的词就是当前时刻预测生成的词</b></span>。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f806bae84c130ec56d17d"><li>神经元工作机制总结</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f806bae84c130ec56d17d"><li><span class="notion-red"><b>接收输入</b></span>：每个 RNN 神经元接收来自输入数据 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 和前一时刻的隐藏状态 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>。</li><li><span class="notion-red"><b>更新隐藏状态</b></span>：神经元通过一个加权和（由权重矩阵和偏置项组成）更新当前时刻的隐藏状态 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>，该隐藏状态包含了来自过去的记忆以及当前输入的信息。</li><li><span class="notion-red"><b>输出计算</b></span>：基于当前隐藏状态 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>，神经元生成当前时刻的输出 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>，该输出可以用于任务的最终预测。</li></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-30ae64bde40f800c9f24e710d4751fbf" data-id="30ae64bde40f800c9f24e710d4751fbf"><span><div id="30ae64bde40f800c9f24e710d4751fbf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#30ae64bde40f800c9f24e710d4751fbf" title="12_RNN层(循环网络层)_API演示"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12_RNN层(循环网络层)_API演示</span></span></h2><ul class="notion-list notion-list-disc notion-block-30ae64bde40f8012a0e5daaf6afa057c"><li>API介绍</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f8012a0e5daaf6afa057c"></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f806cafe5fd7af6aec644"><li>参数意义是：</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f806cafe5fd7af6aec644"><li><code class="notion-inline-code">input_size</code>：输入数据的维度，一般设为词向量的维度；</li><li><code class="notion-inline-code">hidden_size</code>：隐藏层 h 的维度，也是当前层神经元的输出维度；</li><li><code class="notion-inline-code">num_layers</code>: 隐藏层 h 的层数，默认为 1。</li><li>将 RNN 实例化就可以将数据送入进行处理。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f8053b716e626c04e48d9"><li> 输入数据和输出结果</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f8053b716e626c04e48d9"><li>将 RNN 实例化就可以将数据送入其中进行处理。</li><li>输入数据：输入主要包括词嵌入的 x、初始的隐藏层 h0。</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f8010ab5df76ff1b63a50"><li>x 的表示形式为 [seq_len, batch, input_size]，即 [句子的长度, batch的大小, 词向量的维度]。</li><li>h0 的表示形式为[num_layers, batch, hidden_size]，即[隐藏层的层数, batch的大, 隐藏层 h 的维数]。</li></ul><li>输出结果：主要包括输出结果 output，最后一层的 hn。</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f804bba03c02656995dfc"><li>output 的表示形式与输入 x 类似，为[seq_len, batch, hidden_size]，即 [句子的长度, batch 的大小, 输出向量的维度]。</li><li>hn 的表示形式与输入 h0 一样，为[num_layers, batch, hidden_size]，即[隐藏层的层数, batch 的大, 隐藏层 h 的维度]。</li></ul></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80bc9664f7f1649c5336"><li>案例演示：<b><a class="notion-link" href="https://github.com/ZZHow1024/NN-DL-Learning/blob/main/Day07/04_rnn_layer_introduction.py" target="_blank" rel="noopener noreferrer">04_rnn_layer_introduction.py</a></b>（RNN层简介）</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-30ae64bde40f8004b947e36ff3b2c851" data-id="30ae64bde40f8004b947e36ff3b2c851"><span><div id="30ae64bde40f8004b947e36ff3b2c851" class="notion-header-anchor"></div><a class="notion-hash-link" href="#30ae64bde40f8004b947e36ff3b2c851" title="13_RNN_AI歌词生成器案例_构建词表"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13_RNN_AI歌词生成器案例_构建词表</span></span></h2><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80efb483d1902296fa21"><li>项目需求</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80efb483d1902296fa21"><li>文本生成任务是一种常见的自然语言处理任务，输入一个开始词能够预测出后面的词序列。本案例将会使用循环神经网络来实现周杰伦歌词生成任务。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80d2be85e0911dafd065"><li>数据集</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80d2be85e0911dafd065"><li>收集了周杰伦从第一张专辑《Jay》到第十张专辑《跨时代》中的歌词，来训练神经网络模型，当模型训练好后，我们就可以用这个模型来创作歌词。</li><li>数据集共有 5819 行文本。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80f4bd3ececa98899f0a"><li>获取数据集并构建词表</li><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80f4bd3ececa98899f0a"><li>在进行自然语言处理任务之前，首要做的就是构建词表。</li><li>词表是将数据进行分词，然后给每一个词分配一个唯一的编号，便于我们送入词嵌入层获取每个词的词向量。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80babae4f8341699cd2f"><li>对周杰伦歌词的数据进行处理构建词表，整体流程是：获取文本数据、分词并进行去重、构建词表。</li></ul><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80e698cde86b0bf8d039"><li>案例演示：<b><a class="notion-link" href="https://github.com/ZZHow1024/NN-DL-Learning/blob/main/Day07/05_rnn_lyrics_generator.py" target="_blank" rel="noopener noreferrer">05_rnn_lyrics_generator.py</a></b>（RNN_AI歌词生成器）</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-30ae64bde40f80e7b788c2038a4859ca" data-id="30ae64bde40f80e7b788c2038a4859ca"><span><div id="30ae64bde40f80e7b788c2038a4859ca" class="notion-header-anchor"></div><a class="notion-hash-link" href="#30ae64bde40f80e7b788c2038a4859ca" title="14_RNN_AI歌词生成器案例_构建数据集"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">14_RNN_AI歌词生成器案例_构建数据集</span></span></h2><ul class="notion-list notion-list-disc notion-block-30ae64bde40f80658cc3f69faea866b2"><li>在训练的时候，为了便于读取语料，并送入网络，所以我们会构建一个 Dataset 对象。</li></ul><ul class="notion-list notion-list-disc notion-block-30be64bde40f8054b863c8041bb9edb7"><li>案例演示：<b><a class="notion-link" href="https://github.com/ZZHow1024/NN-DL-Learning/blob/main/Day07/05_rnn_lyrics_generator.py" target="_blank" rel="noopener noreferrer">05_rnn_lyrics_generator.py</a></b>（RNN_AI歌词生成器）</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-30ae64bde40f80388063f762a9cfbe38" data-id="30ae64bde40f80388063f762a9cfbe38"><span><div id="30ae64bde40f80388063f762a9cfbe38" class="notion-header-anchor"></div><a class="notion-hash-link" href="#30ae64bde40f80388063f762a9cfbe38" title="15_RNN_AI歌词生成器案例_搭建神经网络"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">15_RNN_AI歌词生成器案例_搭建神经网络</span></span></h2><ul class="notion-list notion-list-disc notion-block-30be64bde40f80798d40d1402ff80cda"><li>用于实现《歌词生成》的网络模型，主要包含了三个层</li><ul class="notion-list notion-list-disc notion-block-30be64bde40f80798d40d1402ff80cda"><li><span class="notion-red"><b>词嵌入层</b></span>：用于将语料转换为词向量。</li><li><span class="notion-red"><b>循环网络层</b></span>：提取句子语义。</li><li><span class="notion-red"><b>全连接层</b></span>：输出对词典中每个词的预测概率。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-30be64bde40f80abaf5ff441ae864267"><li>案例演示：<b><a class="notion-link" href="https://github.com/ZZHow1024/NN-DL-Learning/blob/main/Day07/05_rnn_lyrics_generator.py" target="_blank" rel="noopener noreferrer">05_rnn_lyrics_generator.py</a></b>（RNN_AI歌词生成器）</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-30ae64bde40f80fb8877e838f03ad796" data-id="30ae64bde40f80fb8877e838f03ad796"><span><div id="30ae64bde40f80fb8877e838f03ad796" class="notion-header-anchor"></div><a class="notion-hash-link" href="#30ae64bde40f80fb8877e838f03ad796" title="16_RNN_AI歌词生成器案例_模型训练"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">16_RNN_AI歌词生成器案例_模型训练</span></span></h2><ul class="notion-list notion-list-disc notion-block-30be64bde40f804ba885d3f8d53af1f4"><li>前面的准备工作完成之后，可以编写训练函数。训练函数主要负责编写数据迭代、送入网络、计算损失、反向传播、更新参数，其流程基本较为固定。</li></ul><ul class="notion-list notion-list-disc notion-block-30be64bde40f809da17fc4b85960ae5c"><li>由于要实现文本生成，文本生成本质上，输入一串文本，预测下一个文本，也属于分类问题，所以，使用多分类交叉熵损失函数。优化方法有 SGB、AdaGrad、Adam 等，在这里我们选择学习率、梯度自适应的 Adam 算法作为我们的优化方法。</li></ul><ul class="notion-list notion-list-disc notion-block-30be64bde40f80a09875f08836065e5e"><li>训练完成之后，使用 torch.save 方法将模型持久化存储。</li></ul><ul class="notion-list notion-list-disc notion-block-30be64bde40f80bfaedaf7832577f0fc"><li>案例演示：<b><a class="notion-link" href="https://github.com/ZZHow1024/NN-DL-Learning/blob/main/Day07/05_rnn_lyrics_generator.py" target="_blank" rel="noopener noreferrer">05_rnn_lyrics_generator.py</a></b>（RNN_AI歌词生成器）</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-30ae64bde40f8079876fdebd7a0b5e28" data-id="30ae64bde40f8079876fdebd7a0b5e28"><span><div id="30ae64bde40f8079876fdebd7a0b5e28" class="notion-header-anchor"></div><a class="notion-hash-link" href="#30ae64bde40f8079876fdebd7a0b5e28" title="17_RNN_AI歌词生成器案例_模型测试"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">17_RNN_AI歌词生成器案例_模型测试</span></span></h2><ul class="notion-list notion-list-disc notion-block-30be64bde40f80889b99e7080fa610dc"><li>从磁盘加载训练好的模型，进行预测。预测函数，输入第一个指定的词，将该词输入网路，预测出下一个词，再将预测的出的词再次送入网络，预测出下一个词，以此类推，直到预测出指定长度的内容。</li></ul><ul class="notion-list notion-list-disc notion-block-30be64bde40f80dfa10df551d78aab50"><li>案例演示：<b><a class="notion-link" href="https://github.com/ZZHow1024/NN-DL-Learning/blob/main/Day07/05_rnn_lyrics_generator.py" target="_blank" rel="noopener noreferrer">05_rnn_lyrics_generator.py</a></b>（RNN_AI歌词生成器）</li></ul></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Transformer算法原理]]></title>
            <link>http://blog.zzhow.com/article/TransformerAlgorithmPrinciple</link>
            <guid>http://blog.zzhow.com/article/TransformerAlgorithmPrinciple</guid>
            <pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Transformer算法原理，包含 Transformer算法背景与整体架构；文本数值化、词嵌入与位置编码；自注意力机制；多头注意力机制；填充掩码与因果掩码；残差连接、层归一化与前馈神经网络；编码器、解码器与交叉注意力；Transformer的训练与推理；PyTorch代码实现。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-39ee64bde40f80c5905fed1a1e830d0b"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-39ee64bde40f81efb9aeefeab970ea65">@ZZHow(ZZHow1024)</div><div class="notion-text notion-block-39ee64bde40f81a2aa06d5a70c91c8df">参考课程：</div><div class="notion-text notion-block-39ee64bde40f81f1a5cdf3fa3d33b76d"><b><a class="notion-link" href="https://www.bilibili.com/video/BV1ej1EBWEWu" target="_blank" rel="noopener noreferrer">《Transformer 算法原理与实战》</a></b></div><div class="notion-text notion-block-39ee64bde40f81fca0dcdcf6605edd2f">参考论文：</div><div class="notion-text notion-block-39ee64bde40f8100a9f5c28ac662f9a3"><b><a class="notion-link" href="https://arxiv.org/abs/1706.03762" target="_blank" rel="noopener noreferrer">Attention Is All You Need</a></b></div><figure class="notion-asset-wrapper notion-asset-wrapper-embed"><div style="height:500px;position:relative"><iframe class="notion-asset-object-fit" src="https://docs.google.com/viewer?embedded=true&amp;url=https%3A%2F%2Farxiv.org%2Fpdf%2F1706.03762" title="iframe embed" frameBorder="0" loading="lazy" scrolling="auto" allowfullscreen=""></iframe></div></figure><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39ee64bde40f81c1b96ad3d9725f8990" data-id="39ee64bde40f81c1b96ad3d9725f8990"><span><div id="39ee64bde40f81c1b96ad3d9725f8990" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81c1b96ad3d9725f8990" title="01_Transformer_算法背景"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">01_Transformer_算法背景</span></span></h3><ol start="1" class="notion-list notion-list-numbered notion-block-39ee64bde40f81348cadd1b982e3a771" style="list-style-type:decimal"><li>传统 RNN 按时间步递归计算，后一个状态依赖前一个状态，难以充分并行。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-39ee64bde40f81239a3ec185d20fd3e2" style="list-style-type:decimal"><li>长序列经过多步信息传递，容易出现长距离依赖难以建模的问题。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-39ee64bde40f8001940cc1910156a9e6" style="list-style-type:decimal"><li>Transformer 不使用循环或卷积作为主体，而是以<span class="notion-red"><b>注意力机制</b></span>直接建立任意两个位置之间的联系。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-39ee64bde40f805b96a1c7e1a5a8415b" style="list-style-type:decimal"><li>训练时，同一层中的所有位置可以并行计算；任意两个位置之间的信息传递路径也更短。</li></ol><ul class="notion-list notion-list-disc notion-block-39ee64bde40f815ab448e06d158b3891"><li>Transformer 最初用于<span class="notion-red"><b>机器翻译</b></span>，采用完整的 <span class="notion-red"><b>Encoder—Decoder 架构</b></span>。后来常见模型可以看成对它的不同取舍：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f815ab448e06d158b3891"><li><span class="notion-red"><b>Encoder-only</b></span>：侧重<span class="notion-red"><b>理解</b></span>，例如 BERT。</li><li><span class="notion-red"><b>Decoder-only</b></span>：侧重自回归<span class="notion-red"><b>生成</b></span>，例如 GPT。</li><li><span class="notion-red"><b>Encoder—Decoder</b></span>：适合<span class="notion-red"><b>输入到输出的序列转换</b></span>，例如翻译、摘要。</li></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39ee64bde40f81108f31db18c85d76a6" data-id="39ee64bde40f81108f31db18c85d76a6"><span><div id="39ee64bde40f81108f31db18c85d76a6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81108f31db18c85d76a6" title="02_Transformer_整体架构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">02_Transformer_整体架构</span></span></h3><div class="notion-text notion-block-39ee64bde40f8183b0f1d1b7fdc1d9aa">Transformer Encoder—Decoder 整体架构</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-39ee64bde40f8199b240e8e212360af4"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://www.notion.so/image/attachment%3A1728503c-57c5-490c-913d-0b6521f75740%3A1728503c-57c5-490c-913d-0b6521f75740.png?table=block&amp;id=39ee64bd-e40f-8199-b240-e8e212360af4&amp;t=39ee64bd-e40f-8199-b240-e8e212360af4" alt="Transformer Encoder—Decoder 整体架构" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">Transformer Encoder—Decoder 整体架构</figcaption></div></figure><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81da81c6f88f7dcd2a1c"><li>完整 Transformer 由<span class="notion-red"><b>编码器</b></span>和<span class="notion-red"><b>解码器</b></span>两部分组成：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81da81c6f88f7dcd2a1c"><li>编码器读取源序列，输出包含上下文信息的 <code class="notion-inline-code">memory</code>。</li><li>解码器读取已生成的目标序列，并通过交叉注意力查询编码器输出。</li><li>解码器顶端经过线性层与 Softmax，得到下一个 token 的概率分布。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81938856d68fdcbf6db8"><li>原论文中，Encoder Layer 和 Decoder Layer 均重复堆叠 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 次；模型维度 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>，注意力头数 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>，前馈层中间维度 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>。这些是<span class="notion-red"><b>经典配置</b></span>，不是 Transformer 的固定限制。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f81b89eb5c3ffc9392313" data-id="39ee64bde40f81b89eb5c3ffc9392313"><span><div id="39ee64bde40f81b89eb5c3ffc9392313" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81b89eb5c3ffc9392313" title="2.1_编码器层"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.1_编码器层</span></span></h4><div class="notion-text notion-block-39ee64bde40f81c4a120d4bcb1c6abf6">每个 Encoder Layer 包含：</div><ol start="1" class="notion-list notion-list-numbered notion-block-39ee64bde40f814189e9c8d15f3fe1f3" style="list-style-type:decimal"><li><span class="notion-red"><b>多头自注意力</b></span>（Multi-Head Self-Attention）。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-39ee64bde40f81808166d87b90fa70f3" style="list-style-type:decimal"><li><span class="notion-red"><b>残差连接与层归一化</b></span>（Add &amp; Norm）。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-39ee64bde40f81c9ab1dc606a50320f8" style="list-style-type:decimal"><li><span class="notion-red"><b>逐位置前馈网络</b></span>（Feed Forward Network）。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-39ee64bde40f815c8e68eb371a6caa86" style="list-style-type:decimal"><li>再次进行<span class="notion-red"><b>残差连接与层归一化</b></span>。</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f816b971cdbc55ed44c55" data-id="39ee64bde40f816b971cdbc55ed44c55"><span><div id="39ee64bde40f816b971cdbc55ed44c55" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f816b971cdbc55ed44c55" title="2.2_解码器层"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.2_解码器层</span></span></h4><div class="notion-text notion-block-39ee64bde40f8102830beb4bb50333d0">每个 Decoder Layer 比编码器多一个子层：</div><ol start="1" class="notion-list notion-list-numbered notion-block-39ee64bde40f81e28b38fdb6395f07f6" style="list-style-type:decimal"><li>带<span class="notion-red"><b>因果掩码的多头自注意力</b></span>。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-39ee64bde40f8195ba0ae47a2b3fb927" style="list-style-type:decimal"><li><span class="notion-red"><b>多头交叉注意力</b></span>（查询编码器输出）。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-39ee64bde40f8165a9ffe573d9447dd2" style="list-style-type:decimal"><li><span class="notion-red"><b>逐位置前馈网络</b></span>。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-39ee64bde40f8199bf85ee994de2e9ee" style="list-style-type:decimal"><li>每个子层外均有<span class="notion-red"><b>残差连接与层归一化</b></span>。</li></ol><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39ee64bde40f81a88f3ce26334d07edc" data-id="39ee64bde40f81a88f3ce26334d07edc"><span><div id="39ee64bde40f81a88f3ce26334d07edc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81a88f3ce26334d07edc" title="03_输入文本的数值化"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">03_输入文本的数值化</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f818ca1fdf7136283299a" data-id="39ee64bde40f818ca1fdf7136283299a"><span><div id="39ee64bde40f818ca1fdf7136283299a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f818ca1fdf7136283299a" title="3.1_Tokenize_与_Token_ID"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.1_Tokenize_与_Token_ID</span></span></h4><div class="notion-text notion-block-39ee64bde40f8146b2cbe025977c3754">模型不能直接处理字符串，文本需要依次经过：</div><div class="notion-text notion-block-39ee64bde40f80c8ba1ef68492056858"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div><div class="notion-text notion-block-39ee64bde40f814496a1d3d775b1d1a6">假设词表为：</div><div class="notion-text notion-block-39ee64bde40f81f6a90ffc7323a42ecf">则“我是一条狗”可以转换为：</div><div class="notion-text notion-block-39ee64bde40f815a9470d041fed053f2">特殊 token 的常见作用：</div><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8153bc29d20cf44f225e"><li><code class="notion-inline-code">&lt;pad&gt;</code>：把同一批次中的序列补齐到相同长度。</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81d0bec0f5c64de638f8"><li><code class="notion-inline-code">&lt;bos&gt;</code>：标记目标序列<span class="notion-red"><b>开始</b></span>，用于启动解码。</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8145a160f5e1fc263dc3"><li><code class="notion-inline-code">&lt;eos&gt;</code>：标记序列<span class="notion-red"><b>结束</b></span>，推理时生成它即可停止。</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f815d9c22e3b143c3912a"><li><code class="notion-inline-code">&lt;unk&gt;</code>：表示词表中不存在的 token。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f81b69cc5dcba3c5b8a08" data-id="39ee64bde40f81b69cc5dcba3c5b8a08"><span><div id="39ee64bde40f81b69cc5dcba3c5b8a08" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81b69cc5dcba3c5b8a08" title="3.2_词嵌入_Word_Embedding"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.2_词嵌入_Word_Embedding</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f816c983afd71908112df"><li><span class="notion-red"><b>One-hot</b></span> <span class="notion-red"><b>向量维度等于词表大小</b></span>，既稀疏又无法表达语义相似性。词嵌入使用可训练矩阵 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>，把 token ID 映射为稠密向量：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81dc83c0e431c41d292f"><li>其中 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 是词表大小。语义相近的 token 在训练后往往具有更相近的向量表示。</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81e0b594c5f6548bb6e8"><li>原始 Transformer 会将词嵌入乘以 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>，再与位置编码相加：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f81e7a77fd9e3e3248f87" data-id="39ee64bde40f81e7a77fd9e3e3248f87"><span><div id="39ee64bde40f81e7a77fd9e3e3248f87" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81e7a77fd9e3e3248f87" title="3.3_位置编码_Positional_Encoding"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.3_位置编码_Positional_Encoding</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81a6914de695593c5209"><li>自注意力本身只根据向量内容计算相关性，并不知道 token 的先后顺序，因此需要注入位置信息。</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f80a5b4b3f848434591d6"><li>原论文使用固定的正弦、余弦位置编码：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81e6a5d1df61b5188558"><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>：token 在序列中的位置。</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8178ac76cd364adbd1e8"><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>：向量维度索引。</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f812ab979eb56fbdf6c3e"><li>不同维度使用不同频率，使模型能区分绝对位置，也能学习相对距离。</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8182a8daf8bb2a1b9523"><li>实际模型也常使用可学习位置嵌入或旋转位置编码，但它们不改变“向模型注入顺序信息”这一目的。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39ee64bde40f816fa4c4c54bb09a179f" data-id="39ee64bde40f816fa4c4c54bb09a179f"><span><div id="39ee64bde40f816fa4c4c54bb09a179f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f816fa4c4c54bb09a179f" title="04_自注意力机制_Self-Attention"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">04_自注意力机制_Self-Attention</span></span></h3><ul class="notion-list notion-list-disc notion-block-39ee64bde40f810d958bddb97a60f1af"><li>自注意力要解决的问题是：对于当前位置，序列中的其他 token 各有多重要？</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81e2afcaec049dfe1dd0"><li>例如处理“我喜欢打篮球”中的“打”时，模型可以给“喜欢”和“篮球”更高权重，再把所有位置的信息加权汇总，得到“打”的上下文表示。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f81f9bfeded86beac3c59" data-id="39ee64bde40f81f9bfeded86beac3c59"><span><div id="39ee64bde40f81f9bfeded86beac3c59" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81f9bfeded86beac3c59" title="4.1_Query、Key_与_Value"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.1_Query、Key_与_Value</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f819280dbd3c4c1d7fe3a"><li>输入矩阵 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 分别乘以三组可训练参数：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81eebcfbeaab1099a7cb"><li>可以直观理解为：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81eebcfbeaab1099a7cb"><li>Query：当前 token 想查询什么信息。</li><li>Key：每个 token 可以用什么特征被匹配。</li><li>Value：匹配成功后真正被汇总的内容。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f811589a2d5437583e5a7"><li>在自注意力中，<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>、<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>、<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 来自同一序列；在交叉注意力中，它们来自不同序列。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f81208650f885a9914b29" data-id="39ee64bde40f81208650f885a9914b29"><span><div id="39ee64bde40f81208650f885a9914b29" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81208650f885a9914b29" title="4.2_缩放点积注意力"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.2_缩放点积注意力</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81709fb7dd26cd572155"><li>缩放点积自注意力的矩阵计算过程</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81709fb7dd26cd572155"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-39ee64bde40f810aace5cfed929cf82a"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://www.notion.so/image/attachment%3A4fafb325-277a-4329-ab41-e567a8d37a6e%3A4fafb325-277a-4329-ab41-e567a8d37a6e.png?table=block&amp;id=39ee64bd-e40f-810a-ace5-cfed929cf82a&amp;t=39ee64bd-e40f-810a-ace5-cfed929cf82a" alt="缩放点积自注意力的矩阵计算过程" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">缩放点积自注意力的矩阵计算过程</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81bfb7c5c10d3e83aa25"><li>完整计算公式为：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81b8ba45cb7c8be4f3f1"><li>计算过程：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81b8ba45cb7c8be4f3f1"><ol start="1" class="notion-list notion-list-numbered notion-block-39ee64bde40f81c08621c184bc468f9f" style="list-style-type:decimal"><li><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>：计算每个 Query 与所有 Key 的相似度。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-39ee64bde40f815e8aa6c86cf8692203" style="list-style-type:decimal"><li>除以 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>：控制点积数值范围，避免 Softmax 过早饱和、梯度过小。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-39ee64bde40f81baafdadc3c863bdc97" style="list-style-type:decimal"><li>加上掩码 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>：把不允许关注的位置设为 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-39ee64bde40f81e8acfbf748c2f418ae" style="list-style-type:decimal"><li>Softmax：将每一行变成和为 1 的注意力权重。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-39ee64bde40f814e8086f6eb74a01ef5" style="list-style-type:decimal"><li>乘以 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>：按权重汇总各位置的信息。</li></ol></ul></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f817188c1ee9e7b9609fa" data-id="39ee64bde40f817188c1ee9e7b9609fa"><span><div id="39ee64bde40f817188c1ee9e7b9609fa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f817188c1ee9e7b9609fa" title="4.3_矩阵形状"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.3_矩阵形状</span></span></h4><table class="notion-simple-table notion-block-39ee64bde40f817ca5caf96c23fec242"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-39ee64bde40f81b7b20ff317844997ba"><td class="" style="width:223px"><div class="notion-simple-table-cell">张量</div></td><td class="" style="width:223px"><div class="notion-simple-table-cell">形状</div></td><td class="" style="width:223px"><div class="notion-simple-table-cell">含义</div></td></tr><tr class="notion-simple-table-row notion-block-39ee64bde40f81e2a0f3c8debef92ac7"><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell">长度为 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 的输入序列</div></td></tr><tr class="notion-simple-table-row notion-block-39ee64bde40f819a8e43c753a385d977"><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell">查询向量</div></td></tr><tr class="notion-simple-table-row notion-block-39ee64bde40f81118f66d7fb1ce27c84"><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell">键向量</div></td></tr><tr class="notion-simple-table-row notion-block-39ee64bde40f8188b4cdff36aaa4f0ad"><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell">值向量</div></td></tr><tr class="notion-simple-table-row notion-block-39ee64bde40f81728f95d5f3bbbaa2b7"><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell">两两位置的注意力分数</div></td></tr><tr class="notion-simple-table-row notion-block-39ee64bde40f81db980fc933a82f13c7"><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell">注意力权重</div></td></tr><tr class="notion-simple-table-row notion-block-39ee64bde40f8157a9f0c8d40250e556"><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell"><span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div></td><td class="" style="width:223px"><div class="notion-simple-table-cell">汇总后的上下文表示</div></td></tr></tbody></table><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8134aeedf063b6464f83"><li>自注意力中通常有 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>；交叉注意力允许查询长度和键值长度不同。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39ee64bde40f81e486f2f92b8ca41e92" data-id="39ee64bde40f81e486f2f92b8ca41e92"><span><div id="39ee64bde40f81e486f2f92b8ca41e92" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81e486f2f92b8ca41e92" title="05_多头注意力_Multi-Head_Attention"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">05_多头注意力_Multi-Head_Attention</span></span></h3><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8130a6cbed1b22f40b3e"><li>多头注意力机制</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8130a6cbed1b22f40b3e"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-39ee64bde40f81cea505d01ac1540f63"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://www.notion.so/image/attachment%3A266637d7-30d9-4edf-b1bd-feb16377e1c0%3A266637d7-30d9-4edf-b1bd-feb16377e1c0.png?table=block&amp;id=39ee64bd-e40f-81ce-a505-d01ac1540f63&amp;t=39ee64bd-e40f-81ce-a505-d01ac1540f63" alt="多头注意力机制" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">多头注意力机制</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81b59133e92f494586fd"><li>单头注意力只在一个表示子空间中计算相关性。多头注意力将模型维度拆成 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 份，每个头独立学习不同的关注模式：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81e49ca5ebe85c81ff9c"><li>若 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>、<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>，常见设置是每个头 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>。拼接 8 个头后重新得到 512 维，再通过 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 融合。</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f816bbae1ed71188af00b"><li>不同的头可能分别关注：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f816bbae1ed71188af00b"><li>短距离搭配。</li><li>长距离依赖。</li><li>主谓宾关系。</li><li>实体指代。</li><li>标点、边界或其他结构信息。</li></ul></ul><blockquote class="notion-quote notion-block-39ee64bde40f81b2ba2cc31fdf78d947"><div>多头并不等于简单重复同一计算。每个头有独立的投影参数，因此可以在不同子空间中学习关系。</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39ee64bde40f811e82f3ddaa89a99e38" data-id="39ee64bde40f811e82f3ddaa89a99e38"><span><div id="39ee64bde40f811e82f3ddaa89a99e38" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f811e82f3ddaa89a99e38" title="06_注意力掩码_Mask"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">06_注意力掩码_Mask</span></span></h3><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81f4a8a4ccebc1f86cb7"><li>掩码发生在 Softmax 之前：把不允许参与注意力的位置加上 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>，使其 Softmax 权重变为 0。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f81358316ef26fd71e46a" data-id="39ee64bde40f81358316ef26fd71e46a"><span><div id="39ee64bde40f81358316ef26fd71e46a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81358316ef26fd71e46a" title="6.1_填充掩码_Padding_Mask"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.1_填充掩码_Padding_Mask</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81cb84f7ec9bfdcb1633"><li>同一批次中的句子通常长度不同，需要用 <code class="notion-inline-code">&lt;pad&gt;</code> 补齐。填充位置不含语义，应在作为 Key/Value 时被屏蔽。</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81cb84f7ec9bfdcb1633"></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81939b8dc07785fab914"><li>在 PyTorch 的 <code class="notion-inline-code">key_padding_mask</code> 中，布尔值 <code class="notion-inline-code">True</code> 表示该 Key 位置需要忽略。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f81939b5dd134487f1ba3" data-id="39ee64bde40f81939b5dd134487f1ba3"><span><div id="39ee64bde40f81939b5dd134487f1ba3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81939b5dd134487f1ba3" title="6.2_因果掩码_Causal_Mask"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.2_因果掩码_Causal_Mask</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81c0a6c5f4cc9b56a601"><li>自回归生成要求第 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 个位置只能看到自己和之前的位置，不能偷看未来答案。对应的上三角区域需要屏蔽：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8169b469dc90646b41f7"><li>训练时，因果掩码让整条目标序列仍可并行计算，同时保证每个位置只使用合法的历史信息。</li></ul><blockquote class="notion-quote notion-block-39ee64bde40f8118a292f740849a1ba0"><div>PyTorch 易错点：<code class="notion-inline-code">nn.Transformer</code> 的布尔掩码中 <code class="notion-inline-code">True</code> 表示“禁止参与注意力”；而 <code class="notion-inline-code">torch.nn.functional.scaled_dot_product_attention</code> 的布尔 <code class="notion-inline-code">attn_mask</code> 中，<code class="notion-inline-code">True</code> 表示“允许参与注意力”。混用两套语义会产生方向完全相反的结果。</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39ee64bde40f8111935cce25f0d9348f" data-id="39ee64bde40f8111935cce25f0d9348f"><span><div id="39ee64bde40f8111935cce25f0d9348f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f8111935cce25f0d9348f" title="07_Add_&amp;_Norm_与前馈神经网络"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">07_Add_&amp;_Norm_与前馈神经网络</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f8120a406ebbab83aa7fb" data-id="39ee64bde40f8120a406ebbab83aa7fb"><span><div id="39ee64bde40f8120a406ebbab83aa7fb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f8120a406ebbab83aa7fb" title="7.1_残差连接"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.1_残差连接</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81feac7ef39f6d5836f5"><li>每个子层外包裹残差连接：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81208e17d82e58376850"><li>残差连接保留原始信息，并为深层网络提供更直接的梯度通路。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f817e921bea485674e544" data-id="39ee64bde40f817e921bea485674e544"><span><div id="39ee64bde40f817e921bea485674e544" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f817e921bea485674e544" title="7.2_层归一化_Layer_Normalization"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.2_层归一化_Layer_Normalization</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81418ddbe260edf2cb5e"><li>LayerNorm 在单个 token 的特征维度上归一化：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81d48557d624e594176f"><li>原始 Transformer 使用 Post-Norm：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8191878dc929be9e6f0b"><li>许多后续模型改用 Pre-Norm：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8124b3bdf9b7f3cb602f"><li>Pre-Norm 往往更利于深层模型训练；阅读实现时需要先确认归一化发生在子层之前还是之后。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f8135befcd6cd11622cc5" data-id="39ee64bde40f8135befcd6cd11622cc5"><span><div id="39ee64bde40f8135befcd6cd11622cc5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f8135befcd6cd11622cc5" title="7.3_逐位置前馈网络_FFN"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.3_逐位置前馈网络_FFN</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f817a8a9cfb8eddb6d3e2"><li>Transformer 中的逐位置前馈网络</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f817a8a9cfb8eddb6d3e2"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-39ee64bde40f8143aea4d74e9078e48d"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://www.notion.so/image/attachment%3A60a259ef-83f6-4729-b4b0-921fb13c56df%3A60a259ef-83f6-4729-b4b0-921fb13c56df.png?table=block&amp;id=39ee64bd-e40f-8143-aea4-d74e9078e48d&amp;t=39ee64bd-e40f-8143-aea4-d74e9078e48d" alt="Transformer 中的逐位置前馈网络" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">Transformer 中的逐位置前馈网络</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81d881b1d53887372d4d"><li>注意力负责在 token 之间交换信息，FFN 则对每个 token 独立做非线性变换：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f810ca7dbd4bed749228c"><li>所有位置共享同一组 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>、<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>。</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81d0a867e7cb6f89cfae"><li>不同位置之间互不混合，因此可以并行计算。</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f810ea9eedb3de15d2a43"><li>原论文使用 ReLU，并将 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 维先升到 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 维，再降回 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 维。</li></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81189030c8c22c7219ad"><li>现代模型也常使用 GELU、SiLU 或门控 FFN。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39ee64bde40f810a8d7be0c2727d84a1" data-id="39ee64bde40f810a8d7be0c2727d84a1"><span><div id="39ee64bde40f810a8d7be0c2727d84a1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f810a8d7be0c2727d84a1" title="08_Encoder、Decoder_与交叉注意力"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">08_Encoder、Decoder_与交叉注意力</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f816aa73bca74a5aa34cc" data-id="39ee64bde40f816aa73bca74a5aa34cc"><span><div id="39ee64bde40f816aa73bca74a5aa34cc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f816aa73bca74a5aa34cc" title="8.1_编码器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.1_编码器</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f819a8e77fefc21003bb2"><li>编码器中的自注意力满足：</li></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8121b9a5ea2cbd7bf60c"><li>经过多层编码后，每个源 token 都得到融合全句信息的表示，统一记为 <code class="notion-inline-code">memory</code>。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f81babaf3cc55b8d9cb8c" data-id="39ee64bde40f81babaf3cc55b8d9cb8c"><span><div id="39ee64bde40f81babaf3cc55b8d9cb8c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81babaf3cc55b8d9cb8c" title="8.2_解码器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.2_解码器</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81d087c6e26d8b987842"><li>解码器包含两种注意力：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81d087c6e26d8b987842"><li>因果自注意力：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>，只读取已经出现的目标 token。</li><li>交叉注意力：Query 来自解码器，Key 和 Value 来自编码器输出。</li></ul></ul><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><span role="button" tabindex="0" class="notion-equation notion-equation-block"><span></span></span><ul class="notion-list notion-list-disc notion-block-39ee64bde40f814c8c5cfa3777aeec24"><li>因此，解码器中的每个目标位置都能按需查询整个源序列。源序列长度 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 与目标序列长度 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 可以不同，交叉注意力权重矩阵形状为 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39ee64bde40f8116a802edeb0058a8c2" data-id="39ee64bde40f8116a802edeb0058a8c2"><span><div id="39ee64bde40f8116a802edeb0058a8c2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f8116a802edeb0058a8c2" title="09_Transformer_训练与推理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">09_Transformer_训练与推理</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f81a8a9cede1f53cd0937" data-id="39ee64bde40f81a8a9cede1f53cd0937"><span><div id="39ee64bde40f81a8a9cede1f53cd0937" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81a8a9cede1f53cd0937" title="9.1_训练过程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.1_训练过程</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8188a9d1f8fb2b159433"><li>以“我是一条狗”翻译为“I am a dog”为例，目标序列进行右移：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8188a9d1f8fb2b159433"></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81f98a62ca284f041114"><li>训练流程：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81f98a62ca284f041114"><ol start="1" class="notion-list notion-list-numbered notion-block-39ee64bde40f81368e28f30512fb919b" style="list-style-type:decimal"><li>编码器一次性处理完整源序列。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-39ee64bde40f8180b0f8e891c404b556" style="list-style-type:decimal"><li>解码器接收右移后的完整目标序列。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-39ee64bde40f811c9f80c9c65cff4ed2" style="list-style-type:decimal"><li>因果掩码阻止当前位置读取未来 token。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-39ee64bde40f81949fe6df194d08b31f" style="list-style-type:decimal"><li>每个位置同时预测下一个 token。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-39ee64bde40f81a5bbe0e2cf6d100361" style="list-style-type:decimal"><li>对所有非 <code class="notion-inline-code">&lt;pad&gt;</code> 位置计算交叉熵损失，并反向传播更新参数。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81f996f5ea5e8a0df918"><li>这种做法常称为 Teacher Forcing：训练阶段使用真实历史 token 作为解码器输入。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f812badaaef820d780987" data-id="39ee64bde40f812badaaef820d780987"><span><div id="39ee64bde40f812badaaef820d780987" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f812badaaef820d780987" title="9.2_推理过程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.2_推理过程</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f810fa000edb7495db3e3"><li>Transformer 自回归推理过程</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f810fa000edb7495db3e3"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-39ee64bde40f8120923efb5b9d7b0330"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://www.notion.so/image/attachment%3Ae90de08f-cc58-4f84-a3ef-99e561d0a383%3Ae90de08f-cc58-4f84-a3ef-99e561d0a383.png?table=block&amp;id=39ee64bd-e40f-8120-923e-fb5b9d7b0330&amp;t=39ee64bd-e40f-8120-923e-fb5b9d7b0330" alt="Transformer 自回归推理过程" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">Transformer 自回归推理过程</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f813e8118fb3d2d1a412c"><li>推理时没有完整目标答案，需要逐步生成：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f813e8118fb3d2d1a412c"><li>每一步把已生成 token 重新送入解码器，预测下一个 token。</li><li>生成 <code class="notion-inline-code">&lt;eos&gt;</code> 或达到最大长度时停止。</li><li>可以使用贪心搜索、束搜索或采样策略选择下一个 token。</li><li>实际部署常缓存历史 Key/Value，避免每一步重复计算全部历史状态；这就是 KV Cache。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81348c4de235cb60ebcb"><li>训练能在目标序列长度维度并行，而自回归推理必须逐 token 进行，这也是大模型生成延迟的重要来源。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39ee64bde40f818fb93efb81d96f8232" data-id="39ee64bde40f818fb93efb81d96f8232"><span><div id="39ee64bde40f818fb93efb81d96f8232" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f818fb93efb81d96f8232" title="10_PyTorch_实现缩放点积注意力"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10_PyTorch_实现缩放点积注意力</span></span></h3><ul class="notion-list notion-list-disc notion-block-39ee64bde40f812c9625e477cd29e475"><li>下面用少量代码复现公式，约定布尔掩码中 <code class="notion-inline-code">True</code> 表示禁止关注：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f812c9625e477cd29e475"></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81aeb502fd180a84ba08"><li>注意：如果某一行所有位置都被屏蔽，那么该行 Softmax 可能得到 <code class="notion-inline-code">NaN</code>。构造掩码时应确保每个有效 Query 至少能关注一个位置。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39ee64bde40f81f98835e22acd0bc3d2" data-id="39ee64bde40f81f98835e22acd0bc3d2"><span><div id="39ee64bde40f81f98835e22acd0bc3d2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f81f98835e22acd0bc3d2" title="11_PyTorch_调用多头注意力与完整_Transformer"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11_PyTorch_调用多头注意力与完整_Transformer</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f818d90fadd05f85baa6f" data-id="39ee64bde40f818d90fadd05f85baa6f"><span><div id="39ee64bde40f818d90fadd05f85baa6f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f818d90fadd05f85baa6f" title="11.1_nn.MultiheadAttention"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11.1_nn.MultiheadAttention</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39ee64bde40f8102870ceca78c72e70f" data-id="39ee64bde40f8102870ceca78c72e70f"><span><div id="39ee64bde40f8102870ceca78c72e70f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f8102870ceca78c72e70f" title="11.2_nn.Transformer_最小前向传播"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11.2_nn.Transformer_最小前向传播</span></span></h4><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81eba1cacd3d4fcb5905"><li><code class="notion-inline-code">nn.Transformer</code> 是便于理解原始架构的参考实现。下面只验证张量流，不包含分词器、Embedding、输出词表映射和损失函数：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81eba1cacd3d4fcb5905"></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81819ed3efcc840e3116"><li>要构成真正的序列生成模型，还需要：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81819ed3efcc840e3116"><ol start="1" class="notion-list notion-list-numbered notion-block-39ee64bde40f8125ad46cf4a2da3c089" style="list-style-type:decimal"><li>源语言与目标语言的 tokenizer、词表。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-39ee64bde40f8122a1d4f147b1019a8d" style="list-style-type:decimal"><li><code class="notion-inline-code">nn.Embedding</code> 与位置编码。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-39ee64bde40f81f58e81c1a3ef15f5fb" style="list-style-type:decimal"><li>将 Transformer 输出映射到词表大小的线性层。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-39ee64bde40f811da072d30faf2fd934" style="list-style-type:decimal"><li>忽略 <code class="notion-inline-code">&lt;pad&gt;</code> 的交叉熵损失。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-39ee64bde40f818591f2f89e2ff5587a" style="list-style-type:decimal"><li>训练循环与自回归解码循环。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f811c8477cd31cac51600"><li>API 参考：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f811c8477cd31cac51600"><li><a class="notion-link" href="https://docs.pytorch.org/docs/stable/generated/torch.nn.MultiheadAttention.html" target="_blank" rel="noopener noreferrer">PyTorch MultiheadAttention</a></li><li><a class="notion-link" href="https://docs.pytorch.org/docs/stable/generated/torch.nn.Transformer.html" target="_blank" rel="noopener noreferrer">PyTorch Transformer</a></li><li><a class="notion-link" href="https://docs.pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html" target="_blank" rel="noopener noreferrer">PyTorch scaled_dot_product_attention</a></li></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39ee64bde40f812ca7abc0121989b947" data-id="39ee64bde40f812ca7abc0121989b947"><span><div id="39ee64bde40f812ca7abc0121989b947" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39ee64bde40f812ca7abc0121989b947" title="12_总结"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12_总结</span></span></h3><ul class="notion-list notion-list-disc notion-block-39ee64bde40f811fa53cdab7158d620f"><li>Transformer 的核心数据流可以压缩为：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f811fa53cdab7158d620f"></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8183adf3d749e59612d8"><li>需要重点区分的概念：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f8183adf3d749e59612d8"><table class="notion-simple-table notion-block-39ee64bde40f81aa9603f6c5242a9db1"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-39ee64bde40f8194930ff5f11688edca"><td class="" style="width:120px"><div class="notion-simple-table-cell">概念</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Query 来源</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Key/Value 来源</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">主要作用</div></td></tr><tr class="notion-simple-table-row notion-block-39ee64bde40f8136bf75d25719232691"><td class="" style="width:120px"><div class="notion-simple-table-cell">编码器自注意力</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">编码器输入</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">编码器输入</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">融合源序列上下文</div></td></tr><tr class="notion-simple-table-row notion-block-39ee64bde40f8121afc9fe36e4fc0902"><td class="" style="width:120px"><div class="notion-simple-table-cell">解码器因果自注意力</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">解码器输入</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">解码器输入</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">只利用已生成的目标内容</div></td></tr><tr class="notion-simple-table-row notion-block-39ee64bde40f81fb881de3cb04452853"><td class="" style="width:120px"><div class="notion-simple-table-cell">交叉注意力</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">解码器状态</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">编码器输出</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">根据目标状态查询源序列</div></td></tr><tr class="notion-simple-table-row notion-block-39ee64bde40f815885dbd30934e17aef"><td class="" style="width:120px"><div class="notion-simple-table-cell">Padding Mask</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">—</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">补齐位置</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">忽略无意义的 <code class="notion-inline-code">&lt;pad&gt;</code></div></td></tr><tr class="notion-simple-table-row notion-block-39ee64bde40f81e88d5bf21d312f4d43"><td class="" style="width:120px"><div class="notion-simple-table-cell">Causal Mask</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">—</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">未来位置</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">防止训练时偷看未来答案</div></td></tr></tbody></table></ul></ul><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81d0a12bec80e8415187"><li>最后记住三点：</li><ul class="notion-list notion-list-disc notion-block-39ee64bde40f81d0a12bec80e8415187"><ol start="1" class="notion-list notion-list-numbered notion-block-39ee64bde40f8167934cf2d2e67c0224" style="list-style-type:decimal"><li>注意力<span class="notion-red"><b>权重来自 Query 与 Key 的匹配</b></span>，真正<span class="notion-red"><b>被汇总</b></span>的是 <span class="notion-red"><b>Value</b></span>。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-39ee64bde40f8178a037c098ba9c019d" style="list-style-type:decimal"><li><span class="notion-red"><b>自注意力</b></span>负责 <span class="notion-red"><b>token 间的信息交换</b></span>，<span class="notion-red"><b>FFN</b></span> 负责<span class="notion-red"><b>每个 token 内部的非线性变换</b></span>。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-39ee64bde40f817aa0faf35209e48cd9" style="list-style-type:decimal"><li><span class="notion-red"><b>训练</b></span>阶段可借助<span class="notion-red"><b>因果掩码并行计算</b></span>，<span class="notion-red"><b>推理</b></span>阶段仍需<span class="notion-red"><b>自回归地逐 token 生成</b></span>。</li></ol></ul></ul></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[循序渐进学Java笔记（Chapter09_项目-房屋出租系统）]]></title>
            <link>http://blog.zzhow.com/article/hspJavaChapter9</link>
            <guid>http://blog.zzhow.com/article/hspJavaChapter9</guid>
            <pubDate>Sat, 03 Feb 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[循序渐进学Java笔记（Chapter09_项目-房屋出租系统）]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-5f44ef55716b40c288d7eb43944ea695"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-sync-block notion-block-6462608cfb1a461d9d6c36e263bcbbde"><div class="notion-text notion-block-b4a4cb35c2af4ca6bdf5981d052128d9">@ZZHow(ZZHow1024)</div><div class="notion-text notion-block-5acd84b3490242b7b649e70f675e2ad2">参考课程:</div><div class="notion-text notion-block-5c73dec79e1446d2beae99ec3a40e727">【<em><b>韩顺平</b></em><b> 循序渐进学Java】</b></div><div class="notion-text notion-block-81ebfbe8091e41ffbfdd078965f959ca">[<a class="notion-link" href="https://www.bilibili.com/video/BV1fh411y7R8" target="_blank" rel="noopener noreferrer">https://www.bilibili.com/video/BV1fh411y7R8</a>]</div><div class="notion-text notion-block-344328bda37b49fdaf999a0dcb376266">本章 Project：</div><div class="notion-row"><a class="notion-bookmark notion-block-d179fc60c1664a2ab1bc543a3a3f4f47" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter09_项目-房屋出租系统" target="_blank" rel="noopener noreferrer"><div><div class="notion-bookmark-title">Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/Chapter09_项目-房屋出租系统 at main · ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java</div><div class="notion-bookmark-description">“韩顺平循序渐进学Java”课程笔记. Contribute to ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java development by creating an account on GitHub.</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fgithub.com%2Ffluidicon.png?table=block&amp;id=d179fc60-c166-4a2a-b1bc-543a3a3f4f47&amp;t=d179fc60-c166-4a2a-b1bc-543a3a3f4f47" alt="Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/Chapter09_项目-房屋出租系统 at main · ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter09_项目-房屋出租系统</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fopengraph.githubassets.com%2F3a97ff4308e958387bd04f596e1f2137051613b3624ddf9353be8310520a797d%2FZZHow1024%2FNotes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java?table=block&amp;id=d179fc60-c166-4a2a-b1bc-543a3a3f4f47&amp;t=d179fc60-c166-4a2a-b1bc-543a3a3f4f47" alt="Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/Chapter09_项目-房屋出租系统 at main · ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java" loading="lazy" decoding="async"/></div></a></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-66298a4520f14251905dbd2b3b96bec6" data-id="66298a4520f14251905dbd2b3b96bec6"><span><div id="66298a4520f14251905dbd2b3b96bec6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#66298a4520f14251905dbd2b3b96bec6" title="0361_房屋出租需求"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0361_房屋出租需求</span></span></h2><ul class="notion-list notion-list-disc notion-block-db3e319746f3406ca9ef48ccea566761"><li>项目需求</li><ul class="notion-list notion-list-disc notion-block-db3e319746f3406ca9ef48ccea566761"><li>实现基于文本界面的《房屋出租软件》。</li><li>能够实现对房屋信息的添加、修改和删除 (用数组实现)，并能够打印房屋明细表。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3eefab4555d3446ab758429152f2bb45"><li>项目界面</li><ul class="notion-list notion-list-disc notion-block-3eefab4555d3446ab758429152f2bb45"><li>主菜单</li><li>新增房源</li><li>查找房源</li><li>删除房源</li><li>修改房源</li><li>房屋列表</li><li>退出系统</li></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-ea9465d92617471db7152257b5d115e8" data-id="ea9465d92617471db7152257b5d115e8"><span><div id="ea9465d92617471db7152257b5d115e8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ea9465d92617471db7152257b5d115e8" title="0362_房屋出租设计"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0362_房屋出租设计</span></span></h2><ul class="notion-list notion-list-disc notion-block-385222c46daf4dff9e74e554accdc278"><li>项目设计-程序框架图(分层模式)</li><ul class="notion-list notion-list-disc notion-block-385222c46daf4dff9e74e554accdc278"><li>系统有哪些类[文件]</li><li>明确类与类的调用关系</li></ul></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3d395203aa0f4dfd9a9a104b1fe3af48"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4b165318-6383-451c-8845-110b786c9f0a%2F24074e5e-10a7-4de1-af7d-f52912b7ec55%2F%25E6%2588%25BF%25E5%25B1%258B%25E5%2587%25BA%25E7%25A7%259F%25E8%25AE%25BE%25E8%25AE%25A1.jpg?table=block&amp;id=3d395203-aa0f-4dfd-9a9a-104b1fe3af48&amp;t=3d395203-aa0f-4dfd-9a9a-104b1fe3af48&amp;width=436.3636169433594&amp;cache=v2" alt="房屋出租设计" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">房屋出租设计</figcaption></div></figure><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-051e1627724a4785af936ec5b31dd5fe" data-id="051e1627724a4785af936ec5b31dd5fe"><span><div id="051e1627724a4785af936ec5b31dd5fe" class="notion-header-anchor"></div><a class="notion-hash-link" href="#051e1627724a4785af936ec5b31dd5fe" title="0363_房屋出租工具类"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0363_房屋出租工具类</span></span></h2><ul class="notion-list notion-list-disc notion-block-90d4e2d55fc2491ca05f987edad0c067"><li>准备工具类<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/utils/Utility.java" target="_blank" rel="noopener noreferrer"><b>Utility.java</b></a>，提高开发效率：</li><ul class="notion-list notion-list-disc notion-block-90d4e2d55fc2491ca05f987edad0c067"><div class="notion-text notion-block-a494b586dc9c417a912d227d06fdf336">在实际开发中，公司都会提供相应的工具类和开发库，可以提高开发效率，程序员也需要能够看懂别人写的代码，并能够正确的调用。</div></ul></ul><ul class="notion-list notion-list-disc notion-block-fcbdb355c4dc410e882efe00e35a7add"><li>解释一个问题：</li><ul class="notion-list notion-list-disc notion-block-fcbdb355c4dc410e882efe00e35a7add"><div class="notion-text notion-block-4276e86528d84686bd0c823a28f55f77">直接使用类.方法() → 因为当一个方法是static时，就是一个静态方法，静态方法可以直接通过类名调用。</div></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-4082da6607af44b29f2b9404f8140f54" data-id="4082da6607af44b29f2b9404f8140f54"><span><div id="4082da6607af44b29f2b9404f8140f54" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4082da6607af44b29f2b9404f8140f54" title="0364_房屋House类"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0364_房屋House类</span></span></h2><ul class="notion-list notion-list-disc notion-block-03be266dc024455f8867cd9bca963ace"><li>项目功能实现-完成House类<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/domain/House.java" target="_blank" rel="noopener noreferrer"><b>House.java</b></a></li><ul class="notion-list notion-list-disc notion-block-03be266dc024455f8867cd9bca963ace"><div class="notion-text notion-block-ce495cd317b540a5b9757d5edb91f92b">编号  房主  电话  地址  月租  状态（未出租 / 已出租）</div></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-fdb706d248b9451e8e64d00fa307968c" data-id="fdb706d248b9451e8e64d00fa307968c"><span><div id="fdb706d248b9451e8e64d00fa307968c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#fdb706d248b9451e8e64d00fa307968c" title="0365_房屋主菜单"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0365_房屋主菜单</span></span></h2><ul class="notion-list notion-list-disc notion-block-37a191f324d04c13af833fbd375f38f4"><li>项目功能实现-显示主菜单和完成退出软件功能</li></ul><ul class="notion-list notion-list-disc notion-block-ae61eccc67c34cebba6648da43d1e0cd"><li>功能说明：</li><ul class="notion-list notion-list-disc notion-block-ae61eccc67c34cebba6648da43d1e0cd"><div class="notion-text notion-block-17820d2589144a1da4ccfc4538621c0c">用户打开软件，可以看到主菜单，可以退出软件。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-b6bb79f2702e440db99fd0eaf58e2f2d"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4b165318-6383-451c-8845-110b786c9f0a%2F242abace-6422-4ce6-b49e-2cb5d388d7fa%2F%25E4%25B8%25BB%25E8%258F%259C%25E5%258D%2595.jpg?table=block&amp;id=b6bb79f2-702e-440d-b99f-d0eaf58e2f2d&amp;t=b6bb79f2-702e-440d-b99f-d0eaf58e2f2d&amp;width=408.3735656738281&amp;cache=v2" alt="主菜单" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">主菜单</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-9b1de7e8ec5842b3a5eafe8dc37fc961"><li>思路分析：</li><ul class="notion-list notion-list-disc notion-block-9b1de7e8ec5842b3a5eafe8dc37fc961"><div class="notion-text notion-block-90bd35dd480f4c83b5b27e7fc9aee374">在<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/view/HouseView.java" target="_blank" rel="noopener noreferrer"><b>HouseView.java</b></a>中，编写一个方法mainMenu，显示菜单。</div></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-969d07bba22342a8a0983c814294a557" data-id="969d07bba22342a8a0983c814294a557"><span><div id="969d07bba22342a8a0983c814294a557" class="notion-header-anchor"></div><a class="notion-hash-link" href="#969d07bba22342a8a0983c814294a557" title="0366_房屋出租列表"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0366_房屋出租列表</span></span></h2><ul class="notion-list notion-list-disc notion-block-ad40a233e4ed4781afe85b94962f5657"><li>项目功能实现-完成显示房屋列表的功能</li></ul><ul class="notion-list notion-list-disc notion-block-8bfebb117acd4198951124fd27d30736"><li>功能说明：</li><ul class="notion-list notion-list-disc notion-block-8bfebb117acd4198951124fd27d30736"><div class="notion-text notion-block-e7ee885559e14ab7b5463d92be2f0788">绘制列表，显示编号  房主  电话  地址  月租  状态（未出租 / 已出租）。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1e1be846328b4e9dbb4f4ce067452c89"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4b165318-6383-451c-8845-110b786c9f0a%2F49b0db6e-e237-49d0-9056-188246c68a86%2F%25E6%2588%25BF%25E5%25B1%258B%25E5%2588%2597%25E8%25A1%25A8.jpg?table=block&amp;id=1e1be846-328b-4e9d-bb4f-4ce067452c89&amp;t=1e1be846-328b-4e9d-bb4f-4ce067452c89&amp;width=665.9921875&amp;cache=v2" alt="房屋列表" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">房屋列表</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-22de3b2950c74fd3a399aec5084cb3ea"><li>思路分析：</li><ul class="notion-list notion-list-disc notion-block-22de3b2950c74fd3a399aec5084cb3ea"><div class="notion-text notion-block-b653dbe0f9e241708eb9623d4af50994">编写<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/view/HouseView.java" target="_blank" rel="noopener noreferrer"><b>HouseView.java</b></a> 和 <a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/service/HouseService.java" target="_blank" rel="noopener noreferrer"><b>HouseService.java</b></a></div></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-a7b548b7eb1f4cce984d256564316ca3" data-id="a7b548b7eb1f4cce984d256564316ca3"><span><div id="a7b548b7eb1f4cce984d256564316ca3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a7b548b7eb1f4cce984d256564316ca3" title="0367_房屋出租添加"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0367_房屋出租添加</span></span></h2><ul class="notion-list notion-list-disc notion-block-c030bde4a7ec45c1a17a10e57693b05b"><li>项目功能实现-添加房屋信息的功能</li></ul><ul class="notion-list notion-list-disc notion-block-f2add4be694540bdb0b050938aaa1fe2"><li>功能说明：</li><ul class="notion-list notion-list-disc notion-block-f2add4be694540bdb0b050938aaa1fe2"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-9652129d923940a593b859ecee759d57"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4b165318-6383-451c-8845-110b786c9f0a%2Ffc6538d2-f839-4986-9497-0413da34bfc1%2F%25E6%25B7%25BB%25E5%258A%25A0%25E6%2588%25BF%25E5%25B1%258B.png?table=block&amp;id=9652129d-9239-40a5-93b8-59ecee759d57&amp;t=9652129d-9239-40a5-93b8-59ecee759d57&amp;width=665.9921875&amp;cache=v2" alt="添加房屋" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">添加房屋</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-a888c08d1a2f48cfb9fb09b24bc94bfe"><li>思路分析：</li><ul class="notion-list notion-list-disc notion-block-a888c08d1a2f48cfb9fb09b24bc94bfe"><div class="notion-text notion-block-154643eb8e254bf4b618faab03aa7269">编写<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/view/HouseView.java" target="_blank" rel="noopener noreferrer"><b>HouseView.java</b></a> 和 <a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/service/HouseService.java" target="_blank" rel="noopener noreferrer"><b>HouseService.java</b></a></div><div class="notion-text notion-block-2d3f800654e140759579d5603a3066b1">规定：新添加的房屋的id按照自增长来。</div></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-69c093c156a4481d93157825850d0033" data-id="69c093c156a4481d93157825850d0033"><span><div id="69c093c156a4481d93157825850d0033" class="notion-header-anchor"></div><a class="notion-hash-link" href="#69c093c156a4481d93157825850d0033" title="0368_房屋出租删除"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0368_房屋出租删除</span></span></h2><ul class="notion-list notion-list-disc notion-block-c92f9b5e6d394ad0aecf8150c89852ad"><li>项目功能实现-完成删除房屋信息的功能</li></ul><ul class="notion-list notion-list-disc notion-block-a0d164e880aa4d55bbda4d90bd6f7854"><li>功能说明：</li><ul class="notion-list notion-list-disc notion-block-a0d164e880aa4d55bbda4d90bd6f7854"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3dfbd3cdd07a4b7487cb92af44c72348"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4b165318-6383-451c-8845-110b786c9f0a%2F9a32e8f0-4af7-4c3b-ab3c-c46ed1a07f5e%2F%25E5%2588%25A0%25E9%2599%25A4%25E6%2588%25BF%25E5%25B1%258B.jpg?table=block&amp;id=3dfbd3cd-d07a-4b74-87cb-92af44c72348&amp;t=3dfbd3cd-d07a-4b74-87cb-92af44c72348&amp;width=1258&amp;cache=v2" alt="删除房屋" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">删除房屋</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-14fb6cb123404673bc36b2bf1ba3d7c5"><li>思路分析：</li><ul class="notion-list notion-list-disc notion-block-14fb6cb123404673bc36b2bf1ba3d7c5"><div class="notion-text notion-block-61301b33d3054700b0bc1be3bafb1457">编写<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/view/HouseView.java" target="_blank" rel="noopener noreferrer"><b>HouseView.java</b></a> 和 <a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/service/HouseService.java" target="_blank" rel="noopener noreferrer"><b>HouseService.java</b></a></div></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-98257194caff43b58f7aadc18e2304aa" data-id="98257194caff43b58f7aadc18e2304aa"><span><div id="98257194caff43b58f7aadc18e2304aa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#98257194caff43b58f7aadc18e2304aa" title="0369_房屋出租退出"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0369_房屋出租退出</span></span></h2><ul class="notion-list notion-list-disc notion-block-471741f4f8f040bf89293796c59f9970"><li>项目功能实现-完善退出确认功能</li></ul><ul class="notion-list notion-list-disc notion-block-6fa3be2383474d3c9ff71523d1005a84"><li>功能说明：</li><ul class="notion-list notion-list-disc notion-block-6fa3be2383474d3c9ff71523d1005a84"><div class="notion-text notion-block-47fe91ecdb3c4d88a350b5eab3148808">要求在退出时提示“确认是否退出(Y/N)：”，必须输入Y/N，否则循环提示。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-eba97670df9946fead2e2f1ecb12c1cd"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4b165318-6383-451c-8845-110b786c9f0a%2F20efd68c-9914-4ee0-8fd2-66ebd98fbf59%2F%25E9%2580%2580%25E5%2587%25BA%25E7%25A1%25AE%25E8%25AE%25A4%25E5%258A%259F%25E8%2583%25BD.jpg?table=block&amp;id=eba97670-df99-46fe-ad2e-2f1ecb12c1cd&amp;t=eba97670-df99-46fe-ad2e-2f1ecb12c1cd&amp;width=408.3735656738281&amp;cache=v2" alt="退出确认功能" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">退出确认功能</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-23db0d5b64d842dbb16b24025f7fd620"><li>思路分析：</li><ul class="notion-list notion-list-disc notion-block-23db0d5b64d842dbb16b24025f7fd620"><div class="notion-text notion-block-ac7a363b5a9b418abb645c746d0622f6">编写<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/view/HouseView.java" target="_blank" rel="noopener noreferrer"><b>HouseView.java</b></a></div></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-e2933eeecd3b4901a9c7e5a4ff9602e5" data-id="e2933eeecd3b4901a9c7e5a4ff9602e5"><span><div id="e2933eeecd3b4901a9c7e5a4ff9602e5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e2933eeecd3b4901a9c7e5a4ff9602e5" title="0370_房屋出租查找"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0370_房屋出租查找</span></span></h2><ul class="notion-list notion-list-disc notion-block-2f974129083f4b32a4d5462dae9b5671"><li>项目功能实现-完成根据id查找房屋信息的功能</li></ul><ul class="notion-list notion-list-disc notion-block-05bed557abee420a94832ce65c71a8a7"><li>功能说明：</li><ul class="notion-list notion-list-disc notion-block-05bed557abee420a94832ce65c71a8a7"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-4297cc346565497ba0a772b13bfe00b6"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4b165318-6383-451c-8845-110b786c9f0a%2Fb20feb36-8850-4b52-ab40-062a9f37d9d4%2F%25E6%259F%25A5%25E6%2589%25BE%25E6%2588%25BF%25E5%25B1%258B.jpg?table=block&amp;id=4297cc34-6565-497b-a0a7-72b13bfe00b6&amp;t=4297cc34-6565-497b-a0a7-72b13bfe00b6&amp;width=1255&amp;cache=v2" alt="查找房屋" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">查找房屋</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-6757dbb3868147608065689905058fa7"><li>思路分析：</li><ul class="notion-list notion-list-disc notion-block-6757dbb3868147608065689905058fa7"><div class="notion-text notion-block-a1ffc123e7b54727a6a1715011909423">编写<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/view/HouseView.java" target="_blank" rel="noopener noreferrer"><b>HouseView.java</b></a> 和 <a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/service/HouseService.java" target="_blank" rel="noopener noreferrer"><b>HouseService.java</b></a></div></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-ac98bf5260b049b288818d53ba7e94df" data-id="ac98bf5260b049b288818d53ba7e94df"><span><div id="ac98bf5260b049b288818d53ba7e94df" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ac98bf5260b049b288818d53ba7e94df" title="0371_房屋出租修改"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0371_房屋出租修改</span></span></h2><ul class="notion-list notion-list-disc notion-block-f0bb1612306941878cfa9e9ed1cfb9ed"><li>项目功能实现-完成修改房屋信息的功能</li></ul><ul class="notion-list notion-list-disc notion-block-8d5e855b8168419b893d1067ac8aa36e"><li>功能说明：</li><ul class="notion-list notion-list-disc notion-block-8d5e855b8168419b893d1067ac8aa36e"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-b8b3801ef63d484fa896c769280f565b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4b165318-6383-451c-8845-110b786c9f0a%2Fda1e5e11-9624-4e90-9766-7f5cc49492fa%2F%25E4%25BF%25AE%25E6%2594%25B9%25E6%2588%25BF%25E5%25B1%258B.jpg?table=block&amp;id=b8b3801e-f63d-484f-a896-c769280f565b&amp;t=b8b3801e-f63d-484f-a896-c769280f565b&amp;width=1255&amp;cache=v2" alt="修改房屋" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">修改房屋</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-59c64711713c4b02b54be51c3512cbcf"><li>思路分析：</li><ul class="notion-list notion-list-disc notion-block-59c64711713c4b02b54be51c3512cbcf"><div class="notion-text notion-block-33747d787ce44128931a894a9d4e4327">编写<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter09_%E9%A1%B9%E7%9B%AE-%E6%88%BF%E5%B1%8B%E5%87%BA%E7%A7%9F%E7%B3%BB%E7%BB%9F/src/com/zzhow/houserent/view/HouseView.java" target="_blank" rel="noopener noreferrer"><b>HouseView.java</b></a></div></ul></ul></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[循序渐进学Java笔记（Chapter12_异常）]]></title>
            <link>http://blog.zzhow.com/article/hspJavaChapter12</link>
            <guid>http://blog.zzhow.com/article/hspJavaChapter12</guid>
            <pubDate>Thu, 15 Feb 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[循序渐进学Java笔记（Chapter12_异常）]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-cbf150744745485782b889f838aa7f13"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-sync-block notion-block-41ee43137c3648afa481566d8a7284cd"><div class="notion-text notion-block-d48625e275b4428d8963b9ac68bcc78e">@ZZHow(ZZHow1024)</div><div class="notion-text notion-block-d5f4485b0a9c444c8590afc011e7a7ca">参考课程:</div><div class="notion-text notion-block-c57428dd38ff4391a1d47e29e2aa277a">【<em><b>韩顺平</b></em><b> 循序渐进学Java】</b></div><div class="notion-text notion-block-d9326441fadf422cae4d56be4dc66515">[<a class="notion-link" href="https://www.bilibili.com/video/BV1fh411y7R8/?p=1" target="_blank" rel="noopener noreferrer">https://www.bilibili.com/video/BV1fh411y7R8</a>]</div><div class="notion-text notion-block-0230b34fedf645f8ad57cdc6624981c3">本章 Project：</div><div class="notion-row"><a class="notion-bookmark notion-block-1da83989493f40158f4cba0a5b65d2b9" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter12_异常" target="_blank" rel="noopener noreferrer"><div><div class="notion-bookmark-title">Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/Chapter12_异常 at main · ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java</div><div class="notion-bookmark-description">“韩顺平循序渐进学Java”课程笔记. Contribute to ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java development by creating an account on GitHub.</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fgithub.com%2Ffluidicon.png?table=block&amp;id=1da83989-493f-4015-8f4c-ba0a5b65d2b9&amp;t=1da83989-493f-4015-8f4c-ba0a5b65d2b9" alt="Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/Chapter12_异常 at main · ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter12_异常</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fopengraph.githubassets.com%2F35578c9f8c2faff54a7b46d6d2590be495f9da5ba28feb857c394881067bf501%2FZZHow1024%2FNotes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java?table=block&amp;id=1da83989-493f-4015-8f4c-ba0a5b65d2b9&amp;t=1da83989-493f-4015-8f4c-ba0a5b65d2b9" alt="Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/Chapter12_异常 at main · ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java" loading="lazy" decoding="async"/></div></a></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-f342fc3c3ae0497bb79c936f357f48ce" data-id="f342fc3c3ae0497bb79c936f357f48ce"><span><div id="f342fc3c3ae0497bb79c936f357f48ce" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f342fc3c3ae0497bb79c936f357f48ce" title="异常：Exception"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">异常：Exception</span></span></h3><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-ed1f56740675440884ab4d425de6b342" data-id="ed1f56740675440884ab4d425de6b342"><span><div id="ed1f56740675440884ab4d425de6b342" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ed1f56740675440884ab4d425de6b342" title="0443_异常处理入门"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0443_异常处理入门</span></span></h2><ul class="notion-list notion-list-disc notion-block-6c64a0bcd3e641f69239575d68abb16e"><li>引出异常和异常处理机制</li><ul class="notion-list notion-list-disc notion-block-6c64a0bcd3e641f69239575d68abb16e"></ul></ul><ul class="notion-list notion-list-disc notion-block-b06e050d62054fa687c8a3a45db8f901"><li>当抛出异常后，程序就退出，不应该出现一个不算致命的问题就导致整个系统崩溃。</li></ul><ul class="notion-list notion-list-disc notion-block-fc2c750604a24ccca5016ad3b1ec4311"><li>可以使用try-catch异常处理机制来解决，保证程序的健壮性。</li></ul><ul class="notion-list notion-list-disc notion-block-431bae2777d84fa59e2a7ac8ccd08dfe"><li>将代码块选中，按快捷键 Ctrl + Alt + t -&gt; 选中try-catch。</li><ul class="notion-list notion-list-disc notion-block-431bae2777d84fa59e2a7ac8ccd08dfe"></ul></ul><div class="notion-text notion-block-8c4abe7a13bd48e8adbc9a693f156ac5">案例演示：<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/exception_" target="_blank" rel="noopener noreferrer"><b>com.zzhow.exception_</b></a> 中的 <a class="notion-link" href="https://github.com/dnx00/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/exception_/Exception_.java" target="_blank" rel="noopener noreferrer"><b>Exception_.java</b></a></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-91014ca8ca5e416dba37395164546881" data-id="91014ca8ca5e416dba37395164546881"><span><div id="91014ca8ca5e416dba37395164546881" class="notion-header-anchor"></div><a class="notion-hash-link" href="#91014ca8ca5e416dba37395164546881" title="0444_异常基本介绍"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0444_异常基本介绍</span></span></h2><ul class="notion-list notion-list-disc notion-block-0bea332383044e8a872b9b300495a920"><li>基本介绍：</li><ul class="notion-list notion-list-disc notion-block-0bea332383044e8a872b9b300495a920"><div class="notion-text notion-block-823ba62a920f4222a06d604cdc0fb3ef">Java语言中，将程序执行中发生的不正常情况称为“异常”。（开发过程中的语法错误和逻辑错误不是异常）</div></ul></ul><ul class="notion-list notion-list-disc notion-block-54a548a1f6ca4444a972dc7a929327e5"><li>执行过程中所发生的异常事件可分为两类</li><ul class="notion-list notion-list-disc notion-block-54a548a1f6ca4444a972dc7a929327e5"><ol start="1" class="notion-list notion-list-numbered notion-block-ad4f60fb24a94f10ad5ccdf92a21a881" style="list-style-type:decimal"><li>Error(错误)：Java虚拟机无法解决的严重问题。如：JVM系统内部错误、资源耗尽等严重情况。比如：StackOverflowError[栈溢出]和OOM(out of memory)，Error 是严重错误，程序会崩溃。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-ddb0b2686026426eb21095e82c41376d" style="list-style-type:decimal"><li>Exception：其它因编程错误或偶然的外在因素导致的一般性问题，可以使用针对性的代码进行处理。</li><ol class="notion-list notion-list-numbered notion-block-ddb0b2686026426eb21095e82c41376d" style="list-style-type:lower-alpha"><div class="notion-text notion-block-70fcdd7186754e4abcbc3fc590f55f94">例如空指针访问，试图读取不存在的文件，网络连接中断等等，Exception 分为两大类：<span class="notion-red">运行时异常</span>[程序运行时发生的异常] 和 <span class="notion-red">编译时异常</span>[编程时编译器检查出的异常]。</div></ol></ol></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-46f05869558b4bfa91689ce1481c225d" data-id="46f05869558b4bfa91689ce1481c225d"><span><div id="46f05869558b4bfa91689ce1481c225d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#46f05869558b4bfa91689ce1481c225d" title="0445_异常体系图"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0445_异常体系图</span></span></h2><ul class="notion-list notion-list-disc notion-block-98c4ab2c606d41f79fdef4d0adfe32af"><li>异常体系图</li><ul class="notion-list notion-list-disc notion-block-98c4ab2c606d41f79fdef4d0adfe32af"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-59ce2574f736483e80ed9dcc4400a13a"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4b165318-6383-451c-8845-110b786c9f0a%2F03bddf71-aa05-4f9d-8ca7-1574eedf704e%2F%25E5%25BC%2582%25E5%25B8%25B8%25E4%25BD%2593%25E7%25B3%25BB%25E5%259B%25BE.png?table=block&amp;id=59ce2574-f736-483e-80ed-9dcc4400a13a&amp;t=59ce2574-f736-483e-80ed-9dcc4400a13a&amp;width=408.3735656738281&amp;cache=v2" alt="异常体系图" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">异常体系图</figcaption></div></figure></ul></ul><ul class="notion-list notion-list-disc notion-block-d9adc999feeb4ecfb6c83b42e8821812"><li>异常体系图的小结：</li><ul class="notion-list notion-list-disc notion-block-d9adc999feeb4ecfb6c83b42e8821812"><ol start="1" class="notion-list notion-list-numbered notion-block-152dd32758864f7ab9a32b63fdab509a" style="list-style-type:decimal"><li>异常分为两大类，运行时异常和编译时异常。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-54fe9f94817342babc8b9a01c8ca13e3" style="list-style-type:decimal"><li>运行时异常，编译器检查不出来，编译器不要求强制处置的异常。一般是指编程时的逻辑错误，是程序员应该避免其出现的异常。java.lang.RuntimeException类及它的子类都是运行时异常。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-649b4d10c2224d949bd50215aed679bd" style="list-style-type:decimal"><li>对于运行时异常，可以不作处理，因为这类异常很普遍，若全处理可能会对程序的可读性和运行效率产生影响。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-22f1fb2091d940cc836fe246cd278af5" style="list-style-type:decimal"><li>编译时异常，是编译器要求必须处置的异常。</li></ol></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-0fb3347f8a224ad984f08b1ee7549086" data-id="0fb3347f8a224ad984f08b1ee7549086"><span><div id="0fb3347f8a224ad984f08b1ee7549086" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0fb3347f8a224ad984f08b1ee7549086" title="0446_五大运行时异常"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0446_五大运行时异常</span></span></h2><ul class="notion-list notion-list-disc notion-block-da0b8c0483aa47c991254cb278b05fca"><li>常见的运行时异常包括：</li><ul class="notion-list notion-list-disc notion-block-da0b8c0483aa47c991254cb278b05fca"><ol start="1" class="notion-list notion-list-numbered notion-block-2fd1163aa87741858da6950171115ceb" style="list-style-type:decimal"><li>NullPointerException空指针异常</li><ol class="notion-list notion-list-numbered notion-block-2fd1163aa87741858da6950171115ceb" style="list-style-type:lower-alpha"><ul class="notion-list notion-list-disc notion-block-01234f68df914d59a8ee8c0a2f35fd3f"><li>当应用程序试图在需要对象的地方使用 nul 时，抛出该异常。</li></ul><div class="notion-text notion-block-8d223b0681054607a292c90f1bb38aff">案例演示：<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/exception_" target="_blank" rel="noopener noreferrer"><b>com.zzhow.exception_</b></a> 中的 <a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/exception_/NullPointerException_.java" target="_blank" rel="noopener noreferrer"><b>NullPointerException_.java</b></a></div></ol></ol><ol start="2" class="notion-list notion-list-numbered notion-block-bc39c7af6e2a477cab407126efbe01a7" style="list-style-type:decimal"><li>ArithmeticException数学运算异常</li><ol class="notion-list notion-list-numbered notion-block-bc39c7af6e2a477cab407126efbe01a7" style="list-style-type:lower-alpha"><ul class="notion-list notion-list-disc notion-block-33a9ef0982e84400a8acb67d68e3a004"><li>当出现异常的运算条件时，抛出此异常。例如：一个整数“除以零”时，抛出此类的一个实例。</li></ul><div class="notion-text notion-block-955cc9715c07495aa1fbd4a61c45ddf8">案例演示：<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/exception_" target="_blank" rel="noopener noreferrer"><b>com.zzhow.exception_</b></a> 中的 <a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/exception_/Exception_.java" target="_blank" rel="noopener noreferrer"><b>Exception_.java</b></a></div></ol></ol><ol start="3" class="notion-list notion-list-numbered notion-block-2af5ce280ce14481a29e12a8b87ca151" style="list-style-type:decimal"><li>ArrayIndexOutOfBoundsException数组下标越界异常</li><ol class="notion-list notion-list-numbered notion-block-2af5ce280ce14481a29e12a8b87ca151" style="list-style-type:lower-alpha"><ul class="notion-list notion-list-disc notion-block-d4cebda79aea4691a3f642c3ee0f5dee"><li>用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小，则该索引为非法索引。</li></ul><div class="notion-text notion-block-bd9abadae1ca4eebb7da95165ccf5275">案例演示：<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/exception_" target="_blank" rel="noopener noreferrer"><b>com.zzhow.exception_</b></a> 中的 <a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/exception_/ArrayIndexOutOfBoundsException_.java" target="_blank" rel="noopener noreferrer"><b>ArrayIndexOutOfBoundsException_.java</b></a></div></ol></ol><ol start="4" class="notion-list notion-list-numbered notion-block-d6860ee9523749b6b7acdcf78e8e7197" style="list-style-type:decimal"><li>ClassCastException类型转换异常</li><ol class="notion-list notion-list-numbered notion-block-d6860ee9523749b6b7acdcf78e8e7197" style="list-style-type:lower-alpha"><ul class="notion-list notion-list-disc notion-block-65cc88fead3b494492bc887a3d1b38c4"><li>当试图将对象强制转换为不是实例的子类时，抛出该异常。</li></ul><div class="notion-text notion-block-e3cde0e082084995a46c8802ec56ad98">案例演示：<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/exception_" target="_blank" rel="noopener noreferrer"><b>com.zzhow.exception_</b></a> 中的 <a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/exception_/ClassCastException_.java" target="_blank" rel="noopener noreferrer"><b>ClassCastException_.java</b></a></div></ol></ol><ol start="5" class="notion-list notion-list-numbered notion-block-ebcf8c8a57ab4cae8e12726d2c760d2f" style="list-style-type:decimal"><li>NumberFormatException数字格式不正确异常</li><ol class="notion-list notion-list-numbered notion-block-ebcf8c8a57ab4cae8e12726d2c760d2f" style="list-style-type:lower-alpha"><ul class="notion-list notion-list-disc notion-block-c207a99fab934e938a56f95d1e8d8247"><li>当应用程序试图将字符串转换成一种数值类型，但该字符串不能转换为适当格式时，抛出该异常 —&gt; 使用异常我们可以确保输入是满足条件数字。</li></ul><div class="notion-text notion-block-0b1e741b33a14e99aedd9ffc49ac9b28">案例演示：<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/exception_" target="_blank" rel="noopener noreferrer"><b>com.zzhow.exception_</b></a> 中的 <a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/exception_/NumberFormatException_.java" target="_blank" rel="noopener noreferrer"><b>NumberFormatException_.java</b></a></div></ol></ol></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-5997e7a2f1274ee6be4c449c0f9047ad" data-id="5997e7a2f1274ee6be4c449c0f9047ad"><span><div id="5997e7a2f1274ee6be4c449c0f9047ad" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5997e7a2f1274ee6be4c449c0f9047ad" title="0447_异常课堂练习"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0447_异常课堂练习</span></span></h2><ul class="notion-list notion-list-disc notion-block-a8c9c857bc4f4225af2db48a27ed562a"><li>介绍：</li><ul class="notion-list notion-list-disc notion-block-a8c9c857bc4f4225af2db48a27ed562a"><div class="notion-text notion-block-df50cc9a8a8a4b98952614ba321a8f9c">编译异常是指在编译期间，就必须处理的异常，否则代码不能通过编译。</div></ul></ul><ul class="notion-list notion-list-disc notion-block-2727f936de2145319412ada8975ec82b"><li>常见的编译异常：</li><ul class="notion-list notion-list-disc notion-block-2727f936de2145319412ada8975ec82b"><li>SQLException //操作数据库时，查询表可能发生异常</li><li>IOException //操作文件时，发生的异常</li><li>FileNotFoundException //当操作一个不存在的文件时，发生异常</li><li>ClassNotFoundException //加载类，而该类不存在时，发生异常</li><li>EOFException // 操作文件，到文件末尾，发生异常</li><li>IllegalArguementException //参数异常</li></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-33c94bd20092473981adb0ea02839242" data-id="33c94bd20092473981adb0ea02839242"><span><div id="33c94bd20092473981adb0ea02839242" class="notion-header-anchor"></div><a class="notion-hash-link" href="#33c94bd20092473981adb0ea02839242" title="0448_异常处理机制"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0448_异常处理机制</span></span></h2><ul class="notion-list notion-list-disc notion-block-756712c360ed40ff925279912ba6c1f1"><li>基本介绍：</li><ul class="notion-list notion-list-disc notion-block-756712c360ed40ff925279912ba6c1f1"><div class="notion-text notion-block-bf6486d4ca7d4e49a581ddd9ca653e2c">异常处理就是当异常发生时，对异常处理的方式。</div></ul></ul><ul class="notion-list notion-list-disc notion-block-7bfc878eb6b7490d870477ff3d24506d"><li>异常处理的方式：</li><ul class="notion-list notion-list-disc notion-block-7bfc878eb6b7490d870477ff3d24506d"><ol start="1" class="notion-list notion-list-numbered notion-block-ad1154967e4f4a8abce3ddb72a3990cb" style="list-style-type:decimal"><li>try-catch-finally</li><ol class="notion-list notion-list-numbered notion-block-ad1154967e4f4a8abce3ddb72a3990cb" style="list-style-type:lower-alpha"><div class="notion-text notion-block-c1735e72b3df4de98fc4044d19d4eaca">程序员在代码中捕获发生的异常，自行处理。</div></ol></ol><ol start="2" class="notion-list notion-list-numbered notion-block-a2b6445842b94375bddb60d67bcbd406" style="list-style-type:decimal"><li>throws</li><ol class="notion-list notion-list-numbered notion-block-a2b6445842b94375bddb60d67bcbd406" style="list-style-type:lower-alpha"><div class="notion-text notion-block-86aa9beadc234355941d48cc62d6c696">将发生的异常抛出，交给调用者(方法)来处理，最顶级的处理者就是JVM。</div></ol></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-03454be6731746b6935c2f803f9fd3a7"><li>throws处理机制图</li><ul class="notion-list notion-list-disc notion-block-03454be6731746b6935c2f803f9fd3a7"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-092e58ac30ac415cbe279f202c9dbec3"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4b165318-6383-451c-8845-110b786c9f0a%2Fd6058351-ddd2-4b95-982a-c04afa62e9e6%2Fthrows%25E5%25A4%2584%25E7%2590%2586%25E6%259C%25BA%25E5%2588%25B6%25E5%259B%25BE.png?table=block&amp;id=092e58ac-30ac-415c-be27-9f202c9dbec3&amp;t=092e58ac-30ac-415c-be27-9f202c9dbec3&amp;width=513.984375&amp;cache=v2" alt="throws处理机制图" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">throws处理机制图</figcaption></div></figure><ol start="1" class="notion-list notion-list-numbered notion-block-d2e1a163d7d4475fa98174a68a56f925" style="list-style-type:decimal"><li>try-catch-finally 和 throws 二选一</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-1418b27b30504f52a11be7d38e291bc2" style="list-style-type:decimal"><li>如果程序员没有显式地处理异常，默认throws</li></ol></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-0d2a929112994e258ab11696b2946fb8" data-id="0d2a929112994e258ab11696b2946fb8"><span><div id="0d2a929112994e258ab11696b2946fb8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0d2a929112994e258ab11696b2946fb8" title="0449_tryCatch"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0449_tryCatch</span></span></h2><ul class="notion-list notion-list-disc notion-block-19149e7034c642d9b641f54850b6ce39"><li>try-catch方式处理异常说明：</li><ul class="notion-list notion-list-disc notion-block-19149e7034c642d9b641f54850b6ce39"><ol start="1" class="notion-list notion-list-numbered notion-block-97322349f1dd44b587028661b4a25943" style="list-style-type:decimal"><li>Java提供try和catch块来处理异常。try块用于包含可能出错的代码。catch块用于处理try块中发生的异常。可以根据需要在程序中有多个数量的try……catch块。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-6b75e6df5e9e434c8e608fbde5274d8b" style="list-style-type:decimal"><li>基本语法：</li><ol class="notion-list notion-list-numbered notion-block-6b75e6df5e9e434c8e608fbde5274d8b" style="list-style-type:lower-alpha"></ol></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-4072d6b9cbf440bc9f6d65fa12d7afd2"><li>注意事项：</li><ul class="notion-list notion-list-disc notion-block-4072d6b9cbf440bc9f6d65fa12d7afd2"><ol start="1" class="notion-list notion-list-numbered notion-block-2355fef5bdb247ebab3485eadb03f104" style="list-style-type:decimal"><li>如果异常发生了，则<span class="notion-red">异常发生后面的代码不会执行</span>，直接进入到catch块。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-14d3e069eeb14aa0a24fda8481c958c1" style="list-style-type:decimal"><li>如果异常没有发生，则顺序执行try的代码块，不会进入到catch。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-675a24f38f9b4335b114a1eb66183020" style="list-style-type:decimal"><li>如果希望不管是否发生异常，都执行某段代码(比如关闭连接，释放资源等)则使用如下代码-finally { }</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-509e4c36ffcb45fb8eac64aa543e5d83" style="list-style-type:decimal"><li>可以有多个catch语句，捕获不同的异常(进行不同的业务处理)，要求父类异常在后，子类异常在前，比如：Exception在后NullPointerException在前，如果发生异常，只会匹配一个catch。</li><ol class="notion-list notion-list-numbered notion-block-509e4c36ffcb45fb8eac64aa543e5d83" style="list-style-type:lower-alpha"></ol></ol><ol start="5" class="notion-list notion-list-numbered notion-block-ec95b152c7bc4d1ead21bf05c689fd27" style="list-style-type:decimal"><li>可以进行 try-finally 配合使用，这种用法<span class="notion-red">相当于没有捕获异常</span>，因此程序会直接崩掉。应用场景，就是执行一段代码，不管是否发生异常，都必须执行某个业务逻辑。</li></ol></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3e43dc7a217f4574bd93877dc5cbc02d" data-id="3e43dc7a217f4574bd93877dc5cbc02d"><span><div id="3e43dc7a217f4574bd93877dc5cbc02d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3e43dc7a217f4574bd93877dc5cbc02d" title="0450_tryCatch练习"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0450_tryCatch练习</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-8bcffd38fd5b42318860c7546c864aa8" data-id="8bcffd38fd5b42318860c7546c864aa8"><span><div id="8bcffd38fd5b42318860c7546c864aa8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8bcffd38fd5b42318860c7546c864aa8" title="就算有return，finall也必须执行。如果finally里没有return，catch里面有return，那就等finally执行完了再去return。"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">就算有return，finall也必须执行。如果finally里没有return，catch里面有return，那就等finally执行完了再去return。</span></span></h3><ul class="notion-list notion-list-disc notion-block-2d961b1cf5a94808bac5c1cded7bd671"><li>总结：</li></ul><ol start="1" class="notion-list notion-list-numbered notion-block-c844a0b7e4a14128937ed6379305bdeb" style="list-style-type:decimal"><li><b>如果没有出现异常</b>，则执行try块中所有语句，不执行catch块中语句，如果有finally，最后还需要执行finally里面的语句。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-48552c79773a415da621f980f8f237a0" style="list-style-type:decimal"><li><b>如果出现异常</b>，则try块中异常发生后，try块剩下的语句不再执行。将执行catch块中的语句，如果有finally，最后还需要执行finally里面的语句。</li></ol><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-445abd7c02374c918ac1f2349bb9e1a9" data-id="445abd7c02374c918ac1f2349bb9e1a9"><span><div id="445abd7c02374c918ac1f2349bb9e1a9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#445abd7c02374c918ac1f2349bb9e1a9" title="0451_tryCatch最佳实践"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0451_tryCatch最佳实践</span></span></h2><ul class="notion-list notion-list-disc notion-block-743c7f2582d4489ead6dd57d47fe4360"><li>案例：如果用户输入的不是一个整数，就提示他反复输入，直到输入一个整数为止。</li></ul><div class="notion-text notion-block-e77ccae6edc748e18d6e6354fec7f2fb">案例演示：<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/trycatch_" target="_blank" rel="noopener noreferrer"><b>com.zzhow.trycatch_</b></a> 中的 <a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/trycatch_/TryCatchExercise.java" target="_blank" rel="noopener noreferrer"><b>TryCatchExercise.java</b></a></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-9febe10049d64a959e2e2abe967f6f34" data-id="9febe10049d64a959e2e2abe967f6f34"><span><div id="9febe10049d64a959e2e2abe967f6f34" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9febe10049d64a959e2e2abe967f6f34" title="0452_throws入门案例"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0452_throws入门案例</span></span></h2><ul class="notion-list notion-list-disc notion-block-12d84bfd908847f5a8b87359465f9db2"><li>基本介绍：</li><ul class="notion-list notion-list-disc notion-block-12d84bfd908847f5a8b87359465f9db2"><ol start="1" class="notion-list notion-list-numbered notion-block-7fe0f98b60dd4bbb817782d6dfd9bc68" style="list-style-type:decimal"><li>如果一个方法(中的语句执行时)可能生成某种异常，但是并不能确定如何处理这种异常，则此方法应显示地声明抛出异常，表明该方法将不对这些异常进行处理，而由该方法的<span class="notion-red">调用者负责处理</span>。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-ef896db06d834fccbec1dcae778d7ff9" style="list-style-type:decimal"><li>在方法声明中用throws语句可以声明抛出异常的列表，throws后面的异常类型可以是方法中产生的异常类型，也可以是它的父类。</li></ol></ul></ul><div class="notion-text notion-block-7ff6bcecd0014bc2a15c228bc55b7355">案例演示：<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/throws_" target="_blank" rel="noopener noreferrer"><b>com.zzhow.throws_</b></a> 中的 <a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/throws_/Throws.java" target="_blank" rel="noopener noreferrer"><b>Throws.java</b></a></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3e6e3f13d75947e5bfdbac445546f901" data-id="3e6e3f13d75947e5bfdbac445546f901"><span><div id="3e6e3f13d75947e5bfdbac445546f901" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3e6e3f13d75947e5bfdbac445546f901" title="0453_throws使用细节"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0453_throws使用细节</span></span></h2><ul class="notion-list notion-list-disc notion-block-3e86b04ce4714e35a9bb32e766bff43c"><li>注意事项和使用细节：</li><ul class="notion-list notion-list-disc notion-block-3e86b04ce4714e35a9bb32e766bff43c"><ol start="1" class="notion-list notion-list-numbered notion-block-9193817e597b4a689d93691ada81b784" style="list-style-type:decimal"><li>对于<span class="notion-red">编译异常</span>，程序中<span class="notion-red">必须处理</span>，比如 try-catch 或者 throws。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-cccc28d21f1346febb89724f19306485" style="list-style-type:decimal"><li>对于运行时异常，程序中如果没有处理，默认就是throws的方式处理。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-41ee985370bc4ce2ae32d8ae15341f7d" style="list-style-type:decimal"><li>子类重写父类的方法时，对抛出异常的规定：子类重写的方法所抛出的异常类型要么和父类抛出的异常一致，要么为父类抛出的异常的类型的子类型。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-e08aac6807c74e77b1d632464e6f4ac1" style="list-style-type:decimal"><li>在throws 过程中，如果有方法 try-catch,就相当于处理异常，就可以不必throws。</li></ol></ul></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-16f9d08c7edc41c38f7a7b32e5f591d7" data-id="16f9d08c7edc41c38f7a7b32e5f591d7"><span><div id="16f9d08c7edc41c38f7a7b32e5f591d7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16f9d08c7edc41c38f7a7b32e5f591d7" title="0454_自定义异常"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0454_自定义异常</span></span></h2><ul class="notion-list notion-list-disc notion-block-772895d255d14f6aa9e5565532d5f57e"><li>基本概念：</li><ul class="notion-list notion-list-disc notion-block-772895d255d14f6aa9e5565532d5f57e"><div class="notion-text notion-block-95aeee0afe824dda9a5e5be088b59bad">当程序中出现了某些“错误”但该错误信息并没有在Throwable子类中描述处理，这个时候可以自己设计异常类，用于描述该错误信息。</div></ul></ul><ul class="notion-list notion-list-disc notion-block-e00a8301df0347caaf7bf20cf15d8f7f"><li>自定义异常的步骤：</li><ul class="notion-list notion-list-disc notion-block-e00a8301df0347caaf7bf20cf15d8f7f"><ol start="1" class="notion-list notion-list-numbered notion-block-29997df892214698886f8b613e640c9e" style="list-style-type:decimal"><li>定义类：自定义异常类名(程序员自己写)继承Exception或RuntimeException。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-29c4b6863bb64136ad0628b3ef87efe9" style="list-style-type:decimal"><li>如果继承Exception，属于编译异常。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-b9bbca80cb15405b9ce9d99725af226c" style="list-style-type:decimal"><li>如果继承RuntimeException，属于运行异常(一般来说，继承RuntimeException)。</li></ol></ul></ul><ul class="notion-list notion-list-disc notion-block-86ceec923c9e4a0eace14a57c64284d2"><li>案例：当我们接收Person对象年龄时，要求范围在18-120之间，否则抛出一个自定义异常(要求 继承RuntimeException)，并给出提示信息。</li></ul><div class="notion-text notion-block-353d39f9757643f1b262f85e85e52318">案例演示：<a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/tree/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/customexception_" target="_blank" rel="noopener noreferrer"><b>com.zzhow.customexception_</b></a> 中的 <a class="notion-link" href="https://github.com/ZZHow1024/Notes_on_the_Course_of_Han_Shunping_Gradually_Learning_Java/blob/main/Chapter12_%E5%BC%82%E5%B8%B8/src/com/zzhow/customexception_/CustomException.java" target="_blank" rel="noopener noreferrer"><b>CustomException.java</b></a></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-49770a6c475a4f89b55961ecf0b8396d" data-id="49770a6c475a4f89b55961ecf0b8396d"><span><div id="49770a6c475a4f89b55961ecf0b8396d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#49770a6c475a4f89b55961ecf0b8396d" title="0455_throwVSthrows"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">0455_throwVSthrows</span></span></h2><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-4b63b4f946944f09a48064f190af2391"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4b165318-6383-451c-8845-110b786c9f0a%2Ffba1d815-612e-4165-907d-bcd89e747eec%2Fthrow%25E5%2592%258Cthrows%25E7%259A%2584%25E5%258C%25BA%25E5%2588%25AB.png?table=block&amp;id=4b63b4f9-4694-4f09-a480-64f190af2391&amp;t=4b63b4f9-4694-4f09-a480-64f190af2391&amp;width=551.984375&amp;cache=v2" alt="throw和throws的区别" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">throw和throws的区别</figcaption></div></figure><ul class="notion-list notion-list-disc notion-block-7e01a8700c4b4294bdfe9612b279de07"><li><b>异常处理用throws，手动生成异常用throw。</b></li></ul></div></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>