[{"content":"1. 挑战与贡献 挑战 模型的多样性和更新速度无法与云基础设施上不断变化、高度多样化的人工智能生产工作负载相匹配 工程师或研究人员需要手动选择现有的生产或开源工作负载，并将其调整为可用于基准测试的形式 贡献 框架：建立了一个可扩展的自动化端到端基础设施，可对真实生产型人工智能工作负载的执行轨迹进行剖析和重现 高精度：通过在warehouse-scale fleet中运行的几个 PyTorch 生产工作负载对 Mystique 进行了评估，结果表明，生成的基准在性能和系统级指标方面与原始基准非常接近 可移植性：展示了跨平台生成基准的可移植性，并评估了 Mystique 可应用的几种情况，包括早期平台评估、子轨迹重放和缩小性能测试 2. 相关工作 Benchmark DeepBench：提供了一套深度神经网络（DNN）使用的基本操作，并在不同平台上对其进行了评估 TBD：确定了八个具有代表性的 DNN 模型，并在不同的深度学习框架和硬件配置上进行了详细的性能分析 DAWNBench：测量训练和推理的端到端性能，以规定的精度为前提，允许软件、算法、通信方法的创新 MLPerf：目前最为流行的Benchmark 仿真工具 Sniper：并行、可扩展的CPU仿真工具，对多核和多处理器进行高度抽象 gem5：一种微架构的仿真器，目前适用于仿真GPU GPGPU-Sim：提供一种时钟周期级别的仿真工具，可以对运行CUDA和OpenCL的Nvidia GPU进行仿真 性能建模 Daydream：根据内核-任务依赖图预测模型在某些优化条件下的运行时间 Habitat：使用波形缩放和 MLP 预测 DNN 训练的执行时间 CM-DARE：提出了一种利用云端 GPU 服务器进行分布式训练的性能模型 性能收集 MicroGrad：收集CPU指标，并使用基于梯度下降的调整机制来生成工作负载克隆和压力测试 PerfProx：根据硬件性能计数器得出的性能指标，生成真实世界数据库应用程序的miniature proxies CAMP：模拟核心性能、内存位置以及它们之间的相互作用，以模仿BigData应用程序 ECHO：重点是利用统计模型克隆分布式云应用中的网络行为，并生成与原始服务的定位和流量特征相似的合成基准 Ditto：提出了一种自动克隆框架，该框架可捕获分布式云应用程序的低级和高级性能指标 G-MAP：为 GPU 应用程序的内存访问模式和并行性建模，以创建内存代理 GPGPU-MiniBench：生成 CUDA GPGPU 内核的miniature proxies，以保持相似的性能 3. 相关背景 Pytorch ATen ops：低层级的Tensor库，是Pytorch的后端，用于执行真实的计算任务（加法、矩阵乘法等） Communication ops：多设备之间的分布式训练通信，通常为异步的。在Pytorch中c10d是一个非常流行的通信库，提供了大量的集合通信API和P2P通信API Fused ops：融合操作，是一种计算加速优化方法，可以把多个操作融合成一个运算操作。CPU中常用NNC作为融合操作的后端，GPU中为NVFuser Custom ops：允许用户实现比默认实现更好的模型块 4. Mystique设计 收集Trace https://github.com/mlcommons/chakra/wiki/Chakra-Execution-Trace-Collection-%E2%80%90-A-Comprehensive-Guide-on-Merging-PyTorch-and-Kineto-Traces\nhttps://pytorch.org/docs/stable/profiler.html\n选择ops ET收集的Trace中包含一些冗余信息，例如：aten::leaner()包含了aten::t()和aten::addmm()两个操作，但是在收集ET的Trace时，这三个操作都会被记录下来\n重建ops Aten ops\n通过IR（Intermediate Representation）实现每一个ATen的算子重建，基于字符串解析的方法构建，最后用TorchScript对IR进行编译，为每个操作符创建可调用函数\nCommunication ops\n为了重现原始工作负载的通信模式，我们需要重放通信操作符及其原始参数，如进程组和消息大小\nCustom ops\n输入输出信息可以被ET收集到，但是无法对此进行重建，因为我们无法获取它的具体实现，因此我们保留了一个接口，用户可以自定义实现这些运算\nFused ops\n当前不支持这些操作，重现时将会跳过，因为它的占比不大，不过未来计划实现它\n管理Args 中间张量：用于计算最终结果的一些中间变量，在它生成的时候保存它，并将其传递给下游的操作以便于构成中间的数据依赖 外部张量：输入输出的张量，在执行之前实例化 重现的时候使用相同的维度，但是内容使用随机数替代\n并行Stream 大多数情况下，都会对计算和通信进行并行，以便于隐藏网络通信开销。通常，从Host到Device侧的数据传输也会优化成一个独立的Stream\n在重现时需要识别出每条Stream所在的Kernel，每个Kernel上执行的操作，如此便可准备多条Stream并在重现时将指定的操作放置在指定的Stream上\n问题：当前的ET不包含Stream信息，因此需要冲Pytorch Profiler处获取Stream信息（https://pytorch.org/tutorials/recipes/recipes/profiler_recipe.html）\n5. 实现方法 以大概8000行代码实现，支持所有基础的ATen，大量的自定义运算符，少量的通用库（例如FBGEMM）和c10d分布式库，支持nccl，gloo，mpi，ucc等4种后端\n允许用户在他们自己的代码中插入Hook（通常只需要20行左右）\n6. 评估验证 测试环境：在10台A100或V100上进行验证，CUDA 11.4，Pytorch 1.14\n测试负载：PARAM，ResNet，ASR，RM\n测试范围\n端对端的测试结果 执行Trace和重放Trace\n不同模型下的重放结果\n对比SM利用率、HBM带宽和功耗等指标\n新平台验证 ","permalink":"https://www.zzudongxiang.com/posts/mystique-benchmark/","summary":"\u003ch2 id=\"1-挑战与贡献\"\u003e1. 挑战与贡献\u003c/h2\u003e\n\u003ch3 id=\"挑战\"\u003e挑战\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e模型的多样性和更新速度无法与云基础设施上不断变化、高度多样化的人工智能生产工作负载相匹配\u003c/li\u003e\n\u003cli\u003e工程师或研究人员需要手动选择现有的生产或开源工作负载，并将其调整为可用于基准测试的形式\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"贡献\"\u003e贡献\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003e框架\u003c/strong\u003e：建立了一个可扩展的自动化端到端基础设施，可对真实生产型人工智能工作负载的执行轨迹进行剖析和重现\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e高精度\u003c/strong\u003e：通过在warehouse-scale fleet中运行的几个 PyTorch 生产工作负载对 Mystique 进行了评估，结果表明，生成的基准在性能和系统级指标方面与原始基准非常接近\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e可移植性\u003c/strong\u003e：展示了跨平台生成基准的可移植性，并评估了 Mystique 可应用的几种情况，包括早期平台评估、子轨迹重放和缩小性能测试\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"2-相关工作\"\u003e2. 相关工作\u003c/h2\u003e\n\u003ch3 id=\"benchmark\"\u003eBenchmark\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eDeepBench：提供了一套深度神经网络（DNN）使用的基本操作，并在不同平台上对其进行了评估\u003c/li\u003e\n\u003cli\u003eTBD：确定了八个具有代表性的 DNN 模型，并在不同的深度学习框架和硬件配置上进行了详细的性能分析\u003c/li\u003e\n\u003cli\u003eDAWNBench：测量训练和推理的端到端性能，以规定的精度为前提，允许软件、算法、通信方法的创新\u003c/li\u003e\n\u003cli\u003eMLPerf：目前最为流行的Benchmark\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"仿真工具\"\u003e仿真工具\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eSniper：并行、可扩展的CPU仿真工具，对多核和多处理器进行高度抽象\u003c/li\u003e\n\u003cli\u003egem5：一种微架构的仿真器，目前适用于仿真GPU\u003c/li\u003e\n\u003cli\u003eGPGPU-Sim：提供一种时钟周期级别的仿真工具，可以对运行CUDA和OpenCL的Nvidia GPU进行仿真\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"性能建模\"\u003e性能建模\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eDaydream：根据内核-任务依赖图预测模型在某些优化条件下的运行时间\u003c/li\u003e\n\u003cli\u003eHabitat：使用波形缩放和 MLP 预测 DNN 训练的执行时间\u003c/li\u003e\n\u003cli\u003eCM-DARE：提出了一种利用云端 GPU 服务器进行分布式训练的性能模型\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"性能收集\"\u003e性能收集\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eMicroGrad：收集CPU指标，并使用基于梯度下降的调整机制来生成工作负载克隆和压力测试\u003c/li\u003e\n\u003cli\u003ePerfProx：根据硬件性能计数器得出的性能指标，生成真实世界数据库应用程序的miniature proxies\u003c/li\u003e\n\u003cli\u003eCAMP：模拟核心性能、内存位置以及它们之间的相互作用，以模仿BigData应用程序\u003c/li\u003e\n\u003cli\u003eECHO：重点是利用统计模型克隆分布式云应用中的网络行为，并生成与原始服务的定位和流量特征相似的合成基准\u003c/li\u003e\n\u003cli\u003eDitto：提出了一种自动克隆框架，该框架可捕获分布式云应用程序的低级和高级性能指标\u003c/li\u003e\n\u003cli\u003eG-MAP：为 GPU 应用程序的内存访问模式和并行性建模，以创建内存代理\u003c/li\u003e\n\u003cli\u003eGPGPU-MiniBench：生成 CUDA GPGPU 内核的miniature proxies，以保持相似的性能\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"3-相关背景\"\u003e3. 相关背景\u003c/h2\u003e\n\u003ch3 id=\"pytorch\"\u003ePytorch\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eATen ops\u003c/strong\u003e：低层级的Tensor库，是Pytorch的后端，用于执行真实的计算任务（加法、矩阵乘法等）\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eCommunication ops\u003c/strong\u003e：多设备之间的分布式训练通信，通常为异步的。在Pytorch中c10d是一个非常流行的通信库，提供了大量的集合通信API和P2P通信API\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFused ops\u003c/strong\u003e：融合操作，是一种计算加速优化方法，可以把多个操作融合成一个运算操作。CPU中常用NNC作为融合操作的后端，GPU中为NVFuser\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eCustom ops\u003c/strong\u003e：允许用户实现比默认实现更好的模型块\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg alt=\"img\" loading=\"lazy\" src=\"/posts/mystique-benchmark/images/image-ojuq-1789197025323-1.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"4-mystique设计\"\u003e4. Mystique设计\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"img\" loading=\"lazy\" src=\"/posts/mystique-benchmark/images/image-fqwp-1789197033042-4.png\"\u003e\u003c/p\u003e","title":"文献阅读《Mystique: Enabling accurate and scalable generation of production AI benchmarks》"},{"content":" 张栋祥 zzudongxiang@163.com | zzudongxiang@gmail.com 研究方向 面向国产 NPU 万卡集群的大模型训练与推理系统级协同优化，以及面向“鹏城云脑 III”智算中心的软硬件协同设计与工程落地。 高性能集合通信：围绕昇腾 910C SIO/HCCS 分层互联与 Die-to-Die 直连架构，设计高带宽、可扩展的集合通信算法与通信优化方案。 功耗建模与能效优化：面向大模型训练/推理负载的细粒度功耗建模、能效度量体系构建与集群级能效协同优化。 资源受限下的推理质量控制：大模型量化部署、访存友好的数据布局优化，以及能效约束下的词元级多模型协同推理。 大规模训练仿真与性能工程：万卡级并行策略分析、性能预测工具链建设与国产集群性能摸底方法学。 工作经历 云脑研究所博士后 | 鹏城实验室 2026.08 ~ 至今 入职“鹏城云脑”网络智能重大科技基础设施团队，继续围绕国产 NPU 万卡集群开展大模型训练与推理的系统级优化研究，重点推进高性能集合通信、功耗建模与能效优化等已有成果的工程化落地与规模验证。 多媒体研发工程师 | 展讯半导体（南京）有限公司 2021.07 ~ 2022.07 负责 Android 平台 Camera IP 的软件设计、功能开发、系统集成与技术支持工作，专项负责 Camera 相关的功耗、性能与深度优化，并积极参与技术难题攻关，分析并处理复杂系统问题。独立承担多媒体领域的需求分析、架构分析和方案设计，确保软件方案满足产品规格与性能目标。因在新项目中表现出色，荣获 2021 年度《优秀新人》称号。 教育背景 华南理工大学 | 博士研究生\u0026nbsp;\u0026nbsp;未来技术学院 2022.08 ~ 2026.06 华南理工大学与鹏城国家实验室联合培养博士生。 鹏城国家实验室智能计算研究部，主要研究方向为 AI 大模型训练并行加速算法、高性能网络通信、软硬件协同设计。 南京大学 | 项目合作\u0026nbsp;\u0026nbsp;现代工程与应用科学学院 2020.07 ~ 2021.01 参与袁洪涛教授组内多个科研项目，并提供支持，并参与部分实验项目设计。 郑州大学 | 本科 \u0026amp; 硕士 2014.09 ~ 2021.06 本科（电子科学与技术专业）：C/C++、MATLAB、数字信号系统、模拟电子技术基础、数字电子技术基础、单片机原理、微机原理等。 硕士（仪器仪表工程专业）：数字图像处理、现代数字信号处理、现代传感技术、数值分析、机器视觉、现代光电测试技术等。 学习成绩优异，多次获得校一等奖学金、优秀学生干部等荣誉称号，综合学习成绩排名前 10% 左右。 科研成果 ➤\u0026nbsp;\u0026nbsp;论文发表： Dongxiang Zhang, et al. “Synchronized Dual-Ring: A Synergistic Algorithm for Bandwidth-Efficient Collective Communication Leveraging Die-to-Die Direct Interconnects.” In IEEE International Parallel and Distributed Processing Symposium (IPDPS), 2026. Dongxiang Zhang, et al. “A DUAL-PATH APPROACH TO OPTIMIZING LLMS: ENTROPY CONSTRAINT FOR EXPLOITATION AND NEURAL PERTURBATION FOR EXPLORATION.” In IEEE International Conference on Acoustics, Speech, and Signal Processing (ICASSP), 2026. Dongxiang Zhang, et al. “NPUPower: A Fine-Grained Power Modeling and Optimization Framework for Large-Language Model Training on Ascend NPUs.” In IEEE Transactions on Parallel and Distributed Systems (TPDS), 2026. Yijia Zhang,Dongxiang Zhang, et al. “TOKCOINFER: TOKEN-LEVEL MULTI-MODEL COLLABORATION FOR ENERGY-EFFICIENT LLM INFERENCE.” In IEEE International Conference on Acoustics, Speech, and Signal Processing (ICASSP), 2026. Yijia Zhang,Dongxiang Zhang, et al. “Improving the Energy Efficiency of AI Clusters Through Variability-Aware Frequency Scaling and Task Allocation.” In Proceedings of the 25th International Conference on Algorithms and Architectures for Parallel Processing (ICA3PP 2025), Zhengzhou, China, October 30 - November 02, 2025. Yijia Zhang,Dongxiang Zhang, et al. “AUE: A Normalized Energy Efficiency Metric for AI Servers under LLM Workloads.” In 2025 IEEE 31st International Conference on Parallel and Distributed Systems (ICPADS 2025), Hefei, China, December 14 - 17, 2025. ➤\u0026nbsp;\u0026nbsp;发明专利： 张栋祥, 张士勋, 李雪宁 等. 双环路芯片结构、集合通信方法、装置、设备和存储介质. CN120780647A[P]. 2025-08-28. 张栋祥, 张士勋, 张尔焜 等. 针对大模型参数的数据处理方法、装置、设备以及介质. CN120806000A[P]. 2025-09-12. 章弋嘉,张栋祥, 王丙强 等. 大模型并行训练场景下的功耗预测方法以及相关设备. CN120822038A[P]. 2025-10-21. 章弋嘉,张栋祥, 王丙强 等. 通信能效优化方法、装置、设备和存储介质. CN121151301A[P]. 2025-12-16. 田永鸿, 张士勋, 王丙强,张栋祥等. 数据传输方法、装置、存储介质及计算机设备. CN119011512A[P]. 2025-01-07. 田永鸿, 张士勋, 王丙强,张栋祥等. 一种智能计算系统架构. CN119204130A[P]. 2025-02-18. 科研经历 “鹏城云脑”网络智能重大科技基础设施项目 （国家重大科技基础设施） 2022-09 ~ 2025-05 核心职责：负责国产“鹏城云脑 III”大规模 NPU 集群的系统优化与通信算法设计，围绕昇腾 910C 芯片的 SIO/HCCS 分层互联架构开展高性能集合通信研究。 设计面向 Die-to-Die 直连互联的同步双环/双环类集合通信算法，协同利用 SIO 与 HCCS 链路，在 4 到 128 NPU 规模下较官方 HCCL 平均通信带宽提升9.15% 到 15.81%；在万亿参数模型训练评估中的暴露通信占比由51.05% 降至 34.19%，端到端性能提升最高达34.35%。 主导昇腾 910B/910C 集群性能摸底与瓶颈定位，围绕矩阵计算、NPU-CPU 通信、统一编址、跨超节点扩展等关键路径，为硬件和驱动团队提供底层测试数据与优化依据。 开发大规模训练仿真工具原型，并完成 NS3-RDMA 插件迁移，为万卡级并行策略分析与性能预测提供工具支撑。 万亿级大模型高效训练与推理平台研发 （广东省重点领域研发计划） 2024-12 ~ 2026-06 核心职责：负责国产算力平台上的大模型训练与推理全栈优化，聚焦显存墙、推理吞吐、部署精度与系统能效的协同设计。 研究并落地 Llama2、DeepSeek-V3、Qwen3 等模型在昇腾 910C 上的混合并行与量化部署方案，完成 DeepSeek 的 INT4/INT8 量化实现与精度评测，将 INT4 量化精度损失控制在 5.6% 以内。 围绕推理能效与质量约束开展系统优化研究，设计词元级多模型协同推理 TokCoInfer，在生成 2k 长文本时实现系统级能耗下降31%，显存峰值增幅不足10%，体现出较强的工程应用价值。 设计“量化数据元数据原子块（QDMAB）”数据结构，针对分块量化矩阵推理过程中的访存瓶颈优化数据布局，减少非合并访存并提升带宽利用率，相关成果已申请发明专利。 导出 PDF ","permalink":"https://www.zzudongxiang.com/about/","summary":"\u003clink rel=\"stylesheet\" href=\"resume.css\"\u003e\n\u003cdiv class=\"resume-page\"\u003e\n\u003cheader class=\"resume-header\"\u003e\n    \u003cdiv class=\"resume-brands\"\u003e\n        \u003cimg class=\"brand-logo pcl-logo\" src=\"images/pcl.png\" alt=\"鹏城实验室\"\u003e\n    \u003c/div\u003e\n    \u003cdiv class=\"resume-identity\"\u003e\n        \u003cdiv class=\"resume-name\"\u003e张栋祥\u003c/div\u003e\n        \u003cdiv class=\"resume-contact\"\u003e\n            \u003cdiv class=\"contact-row emails\"\u003e\n                \u003cspan class=\"contact-item\"\u003e\n                    \u003cimg class=\"contact-icon\" src=\"images/icon/email.svg\" alt=\"\"\u003e\n                    \u003cspan\u003ezzudongxiang@163.com\u003c/span\u003e\n                \u003c/span\u003e\n                \u003cspan class=\"contact-separator\"\u003e|\u003c/span\u003e\n                \u003cspan class=\"contact-item\"\u003e\n                    \u003cimg class=\"contact-icon\" src=\"images/icon/email.svg\" alt=\"\"\u003e\n                    \u003cspan\u003ezzudongxiang@gmail.com\u003c/span\u003e\n                \u003c/span\u003e\n            \u003c/div\u003e\n        \u003c/div\u003e\n    \u003c/div\u003e\n    \u003cdiv class=\"resume-portrait-wrap\"\u003e\n        \u003cimg\n            class=\"resume-portrait\"\n            src=\"images/avatar.png\"\n            alt=\"张栋祥证件照\"\u003e\n    \u003c/div\u003e\n    \u003c/header\u003e\n    \u003csection class=\"resume-section\"\u003e\n        \u003cdiv class=\"section-title\"\u003e\n            \u003cimg class=\"section-icon\" src=\"images/icon/info.svg\" alt=\"\"\u003e\n            \u003cspan class=\"section-title-text\"\u003e研究方向\u003c/span\u003e\u003c/div\u003e\n        \u003cul class=\"resume-list\"\u003e\n            \u003cli\u003e面向国产 NPU 万卡集群的大模型训练与推理系统级协同优化，以及面向“鹏城云脑 III”智算中心的软硬件协同设计与工程落地。\u003c/li\u003e\n            \u003cli\u003e高性能集合通信：围绕昇腾 910C SIO/HCCS 分层互联与 Die-to-Die 直连架构，设计高带宽、可扩展的集合通信算法与通信优化方案。\u003c/li\u003e\n            \u003cli\u003e功耗建模与能效优化：面向大模型训练/推理负载的细粒度功耗建模、能效度量体系构建与集群级能效协同优化。\u003c/li\u003e\n            \u003cli\u003e资源受限下的推理质量控制：大模型量化部署、访存友好的数据布局优化，以及能效约束下的词元级多模型协同推理。\u003c/li\u003e\n            \u003cli\u003e大规模训练仿真与性能工程：万卡级并行策略分析、性能预测工具链建设与国产集群性能摸底方法学。\u003c/li\u003e\n        \u003c/ul\u003e\n    \u003c/section\u003e\n    \u003csection class=\"resume-section\"\u003e\n        \u003cdiv class=\"section-title\"\u003e\n            \u003cimg class=\"section-icon\" src=\"images/icon/toolbox.svg\" alt=\"\"\u003e\n            \u003cspan class=\"section-title-text\"\u003e工作经历\u003c/span\u003e\u003c/div\u003e\n        \u003cdiv class=\"resume-entry\"\u003e\n            \u003cdiv class=\"entry-head\"\u003e\n                \u003cdiv class=\"entry-title\"\u003e云脑研究所博士后\u003cspan class=\"entry-detail\"\u003e | 鹏城实验室\u003c/span\u003e\u003c/div\u003e\n                \u003cdiv class=\"entry-date\"\u003e2026.08 ~ 至今\u003c/div\u003e\u003c/div\u003e\n            \u003cul class=\"resume-list\"\u003e\n                \u003cli\u003e\n                    入职“鹏城云脑”网络智能重大科技基础设施团队，继续围绕国产 NPU 万卡集群开展大模型训练与推理的系统级优化研究，重点推进高性能集合通信、功耗建模与能效优化等已有成果的工程化落地与规模验证。\n                \u003c/li\u003e\n            \u003c/ul\u003e\n            \u003cdiv class=\"entry-head\"\u003e\n                \u003cdiv class=\"entry-title\"\u003e多媒体研发工程师\u003cspan class=\"entry-detail\"\u003e | 展讯半导体（南京）有限公司\u003c/span\u003e\u003c/div\u003e\n                \u003cdiv class=\"entry-date\"\u003e2021.07 ~ 2022.07\u003c/div\u003e\n            \u003c/div\u003e\n            \u003cul class=\"resume-list\"\u003e\n                \u003cli\u003e\n                    负责 Android 平台 Camera IP 的软件设计、功能开发、系统集成与技术支持工作，专项负责 Camera 相关的功耗、性能与深度优化，并积极参与技术难题攻关，分析并处理复杂系统问题。独立承担多媒体领域的需求分析、架构分析和方案设计，确保软件方案满足产品规格与性能目标。因在新项目中表现出色，荣获 2021 年度《优秀新人》称号。\n                \u003c/li\u003e\n            \u003c/ul\u003e\n        \u003c/div\u003e\n    \u003c/section\u003e\n    \u003csection class=\"resume-section\"\u003e\n        \u003cdiv class=\"section-title first-section\"\u003e\n            \u003cimg class=\"section-icon\" src=\"images/icon/graduation.svg\" alt=\"\"\u003e\n            \u003cspan class=\"section-title-text\"\u003e教育背景\u003c/span\u003e\u003c/div\u003e\n        \u003cdiv class=\"resume-entry\"\u003e\n            \u003cdiv class=\"entry-head\"\u003e\n                \u003cdiv class=\"entry-title\"\u003e华南理工大学\u003cspan class=\"entry-detail\"\u003e | 博士研究生\u0026nbsp;\u0026nbsp;未来技术学院\u003c/span\u003e\u003c/div\u003e\n                \u003cdiv class=\"entry-date\"\u003e2022.08 ~ 2026.06\u003c/div\u003e\n            \u003c/div\u003e\n            \u003cul class=\"resume-list\"\u003e\n                \u003cli\u003e华南理工大学与鹏城国家实验室联合培养博士生。\u003c/li\u003e\n                \u003cli\u003e鹏城国家实验室智能计算研究部，主要研究方向为 AI 大模型训练并行加速算法、高性能网络通信、软硬件协同设计。\u003c/li\u003e\n            \u003c/ul\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"resume-entry\"\u003e\n            \u003cdiv class=\"entry-head\"\u003e\n                \u003cdiv class=\"entry-title\"\u003e南京大学\u003cspan class=\"entry-detail\"\u003e | 项目合作\u0026nbsp;\u0026nbsp;现代工程与应用科学学院\u003c/span\u003e\u003c/div\u003e\n                \u003cdiv class=\"entry-date\"\u003e2020.07 ~ 2021.01\u003c/div\u003e\n            \u003c/div\u003e\n            \u003cul class=\"resume-list\"\u003e\n                \u003cli\u003e参与袁洪涛教授组内多个科研项目，并提供支持，并参与部分实验项目设计。\u003c/li\u003e\n            \u003c/ul\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"resume-entry\"\u003e\n            \u003cdiv class=\"entry-head\"\u003e\n                \u003cdiv class=\"entry-title\"\u003e郑州大学\u003cspan class=\"entry-detail\"\u003e | 本科 \u0026amp; 硕士\u003c/span\u003e\u003c/div\u003e\n                \u003cdiv class=\"entry-date\"\u003e2014.09 ~ 2021.06\u003c/div\u003e\u003c/div\u003e\n            \u003cul class=\"resume-list\"\u003e\n                \u003cli\u003e本科（电子科学与技术专业）：C/C++、MATLAB、数字信号系统、模拟电子技术基础、数字电子技术基础、单片机原理、微机原理等。\u003c/li\u003e\n                \u003cli\u003e硕士（仪器仪表工程专业）：数字图像处理、现代数字信号处理、现代传感技术、数值分析、机器视觉、现代光电测试技术等。\u003c/li\u003e\n                \u003cli\u003e学习成绩优异，多次获得校一等奖学金、优秀学生干部等荣誉称号，综合学习成绩排名前 10% 左右。\u003c/li\u003e\u003c/ul\u003e\n        \u003c/div\u003e\n    \u003c/section\u003e\n    \u003csection class=\"resume-section\"\u003e\n        \u003cdiv class=\"section-title\"\u003e\n            \u003cimg class=\"section-icon\" src=\"images/icon/diagram.svg\" alt=\"\"\u003e\n            \u003cspan class=\"section-title-text\"\u003e科研成果\u003c/span\u003e\u003c/div\u003e\n        \u003cdiv class=\"subheading\"\u003e➤\u0026nbsp;\u0026nbsp;论文发表：\u003c/div\u003e\n        \u003cul class=\"resume-list publication-list\"\u003e\n            \u003cli\u003e\n                \u003cstrong\u003eDongxiang Zhang\u003c/strong\u003e, et al. “Synchronized Dual-Ring: A Synergistic Algorithm for Bandwidth-Efficient Collective Communication Leveraging Die-to-Die Direct Interconnects.” In\n                \u003cem\u003eIEEE International Parallel and Distributed Processing Symposium (IPDPS)\u003c/em\u003e, 2026.\n            \u003c/li\u003e\n            \u003cli\u003e\n                \u003cstrong\u003eDongxiang Zhang\u003c/strong\u003e, et al. “A DUAL-PATH APPROACH TO OPTIMIZING LLMS: ENTROPY CONSTRAINT FOR EXPLOITATION AND NEURAL PERTURBATION FOR EXPLORATION.” In\n                \u003cem\u003eIEEE International Conference on Acoustics, Speech, and Signal Processing (ICASSP)\u003c/em\u003e, 2026.\n            \u003c/li\u003e\n            \u003cli\u003e\n                \u003cstrong\u003eDongxiang Zhang\u003c/strong\u003e, et al. “NPUPower: A Fine-Grained Power Modeling and Optimization Framework for Large-Language Model Training on Ascend NPUs.” In\n                \u003cem\u003eIEEE Transactions on Parallel and Distributed Systems (TPDS)\u003c/em\u003e, 2026.\n            \u003c/li\u003e\n            \u003cli\u003eYijia Zhang,\u003cstrong\u003eDongxiang Zhang\u003c/strong\u003e, et al. “TOKCOINFER: TOKEN-LEVEL MULTI-MODEL COLLABORATION FOR ENERGY-EFFICIENT LLM INFERENCE.” In\n                \u003cem\u003eIEEE International Conference on Acoustics, Speech, and Signal Processing (ICASSP)\u003c/em\u003e, 2026.\n            \u003c/li\u003e\n            \u003cli\u003eYijia Zhang,\u003cstrong\u003eDongxiang Zhang\u003c/strong\u003e, et al. “Improving the Energy Efficiency of AI Clusters Through Variability-Aware Frequency Scaling and Task Allocation.” In\n                \u003cem\u003eProceedings of the 25th International Conference on Algorithms and Architectures for Parallel Processing (ICA3PP 2025)\u003c/em\u003e, Zhengzhou, China, October 30 - November 02, 2025.\n            \u003c/li\u003e\n            \u003cli\u003eYijia Zhang,\u003cstrong\u003eDongxiang Zhang\u003c/strong\u003e, et al. “AUE: A Normalized Energy Efficiency Metric for AI Servers under LLM Workloads.” In\n                \u003cem\u003e2025 IEEE 31st International Conference on Parallel and Distributed Systems (ICPADS 2025)\u003c/em\u003e, Hefei, China, December 14 - 17, 2025.\n            \u003c/li\u003e\n        \u003c/ul\u003e\n        \u003cdiv class=\"subheading patent-heading\"\u003e➤\u0026nbsp;\u0026nbsp;发明专利：\u003c/div\u003e\n        \u003cul class=\"resume-list patent-list\"\u003e\n            \u003cli\u003e\n                \u003cstrong\u003e张栋祥\u003c/strong\u003e, 张士勋, 李雪宁 等. 双环路芯片结构、集合通信方法、装置、设备和存储介质. CN120780647A[P]. 2025-08-28.\n            \u003c/li\u003e\n            \u003cli\u003e\n                \u003cstrong\u003e张栋祥\u003c/strong\u003e, 张士勋, 张尔焜 等. 针对大模型参数的数据处理方法、装置、设备以及介质. CN120806000A[P]. 2025-09-12.\n            \u003c/li\u003e\n            \u003cli\u003e\n                章弋嘉,\u003cstrong\u003e张栋祥\u003c/strong\u003e, 王丙强 等. 大模型并行训练场景下的功耗预测方法以及相关设备. CN120822038A[P]. 2025-10-21.\n            \u003c/li\u003e\n            \u003cli\u003e\n                章弋嘉,\u003cstrong\u003e张栋祥\u003c/strong\u003e, 王丙强 等. 通信能效优化方法、装置、设备和存储介质. CN121151301A[P]. 2025-12-16.\n            \u003c/li\u003e\n            \u003cli\u003e\n                田永鸿, 张士勋, 王丙强,\u003cstrong\u003e张栋祥\u003c/strong\u003e等. 数据传输方法、装置、存储介质及计算机设备. CN119011512A[P]. 2025-01-07.\n            \u003c/li\u003e\n            \u003cli\u003e\n                田永鸿, 张士勋, 王丙强,\u003cstrong\u003e张栋祥\u003c/strong\u003e等. 一种智能计算系统架构. CN119204130A[P]. 2025-02-18.\n            \u003c/li\u003e\n        \u003c/ul\u003e\n    \u003c/section\u003e\n    \u003csection class=\"resume-section\"\u003e\n        \u003cdiv class=\"section-title\"\u003e\n            \u003cimg class=\"section-icon\" src=\"images/icon/rss.svg\" alt=\"\"\u003e\n            \u003cspan class=\"section-title-text\"\u003e科研经历\u003c/span\u003e\u003c/div\u003e\n        \u003cdiv class=\"resume-entry\"\u003e\n            \u003cdiv class=\"entry-head\"\u003e\n                \u003cdiv class=\"entry-title\"\u003e“鹏城云脑”网络智能重大科技基础设施项目\n                    \u003cspan class=\"entry-detail\"\u003e（国家重大科技基础设施）\u003c/span\u003e\u003c/div\u003e\n                \u003cdiv class=\"entry-date\"\u003e2022-09 ~ 2025-05\u003c/div\u003e\u003c/div\u003e\n            \u003cul class=\"resume-list\"\u003e\n                \u003cli\u003e\n                    \u003cstrong\u003e核心职责：\u003c/strong\u003e负责国产“鹏城云脑 III”大规模 NPU 集群的系统优化与通信算法设计，围绕昇腾 910C 芯片的 SIO/HCCS 分层互联架构开展高性能集合通信研究。\n                \u003c/li\u003e\n                \u003cli\u003e\n                    设计面向 Die-to-Die 直连互联的同步双环/双环类集合通信算法，协同利用 SIO 与 HCCS 链路，在 4 到 128 NPU 规模下较官方 HCCL 平均通信带宽提升\u003cstrong\u003e9.15% 到 15.81%\u003c/strong\u003e；在万亿参数模型训练评估中的暴露通信占比由\u003cstrong\u003e51.05% 降至 34.19%\u003c/strong\u003e，端到端性能提升最高达\u003cstrong\u003e34.35%\u003c/strong\u003e。\n                \u003c/li\u003e\n                \u003cli\u003e\n                    主导昇腾 910B/910C 集群性能摸底与瓶颈定位，围绕矩阵计算、NPU-CPU 通信、统一编址、跨超节点扩展等关键路径，为硬件和驱动团队提供底层测试数据与优化依据。\n                \u003c/li\u003e\n                \u003cli\u003e\n                    开发大规模训练仿真工具原型，并完成 NS3-RDMA 插件迁移，为万卡级并行策略分析与性能预测提供工具支撑。\n                \u003c/li\u003e\n            \u003c/ul\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"resume-entry\"\u003e\n            \u003cdiv class=\"entry-head\"\u003e\n                \u003cdiv class=\"entry-title\"\u003e万亿级大模型高效训练与推理平台研发\n                    \u003cspan class=\"entry-detail\"\u003e（广东省重点领域研发计划）\u003c/span\u003e\u003c/div\u003e\n                \u003cdiv class=\"entry-date\"\u003e2024-12 ~ 2026-06\u003c/div\u003e\u003c/div\u003e\n            \u003cul class=\"resume-list\"\u003e\n                \u003cli\u003e\n                    \u003cstrong\u003e核心职责：\u003c/strong\u003e负责国产算力平台上的大模型训练与推理全栈优化，聚焦显存墙、推理吞吐、部署精度与系统能效的协同设计。\n                \u003c/li\u003e\n                \u003cli\u003e研究并落地 Llama2、DeepSeek-V3、Qwen3 等模型在昇腾 910C 上的混合并行与量化部署方案，完成 DeepSeek 的 INT4/INT8 量化实现与精度评测，将 INT4 量化精度损失控制在\n                    \u003cstrong\u003e5.6% 以内\u003c/strong\u003e。\n                \u003c/li\u003e\n                \u003cli\u003e\n                    围绕推理能效与质量约束开展系统优化研究，设计词元级多模型协同推理 TokCoInfer，在生成 2k 长文本时实现系统级能耗下降\u003cstrong\u003e31%\u003c/strong\u003e，显存峰值增幅不足\u003cstrong\u003e10%\u003c/strong\u003e，体现出较强的工程应用价值。\n                \u003c/li\u003e\n                \u003cli\u003e\n                    设计“量化数据元数据原子块（QDMAB）”数据结构，针对分块量化矩阵推理过程中的访存瓶颈优化数据布局，减少非合并访存并提升带宽利用率，相关成果已申请发明专利。\n                \u003c/li\u003e\n            \u003c/ul\u003e\n        \u003c/div\u003e\n    \u003c/section\u003e\n    \u003cdiv class=\"resume-actions\"\u003e\n        \u003cbutton type=\"button\" onclick=\"window.print()\"\n            title=\"在弹出的打印窗口中选择「另存为 PDF」即可保存\"\u003e导出 PDF\u003c/button\u003e\n    \u003c/div\u003e\n\u003c/div\u003e","title":"张栋祥 · 个人简历"},{"content":" Alibaba High Performance Network (HPN)\nHPN介绍了一种两层的双平面网络，可以在一个Pod中接入1.5w个GPU，通常需要3层Clos架构的网络才能容纳这么多GPU\nHPN 提出了一种新的双 ToR 设计，以取代传统数据中心网络中的单 ToR\n1. 贡献与挑战 挑战 流量模式\n传统网络无法应对LLM的低熵、周期性、突发的网络特点，传统的数据中心网络一般是高熵的（传统网络中会存在百万条流，但是每条流的利用率特别低，一半小于20%）\nECMP在传统的数据中心的高熵、低利用率的网络中性能表现较好，但是在LLM训练中并不是最佳的\n单点故障的敏感性高\nLLM训练是一个同步过程，所有GPU合作完成一系列迭代，任何一个GPU发生故障都有可能导致整个训练过程出现问题\n对LLM训练影响最大的是与机架顶部（ToR）相关的单点故障，这种故障可能会影响到各种GPU\n生产统计数据显示，LLM训练中出现的故障造成的损失是一般云计算故障的 20 倍\n贡献 非堆叠的双层ToR网络，可以在两个交换机之间直接同步，很好的改善了大规模部署的可信度\n适配最新的51.2Tbps的交换机芯片，可以将1K个GPU部署在Tier 1网络中，使96.3%的训练任务获得高性能的网络\n我们的实验表明，使用HPN的LLM训练吞吐量比传统数据中心网络高14.9倍\n2. 背景知识 LLM的并行策略 DP：每次迭代使用All Reduce同步计算梯度数据\nPP：每次使用Send/Recv传递中间结果\nTP：每次迭代使用All Reduce/All Gather同步输出和对应的梯度\nLLM的流量特征 带宽利用率周期性突发\n流的数量少\n传统的数据中心网络不适用于LLM流量模式\nLLM对单点故障的敏感性 LLM每次的Checkpoint间隔大概在2-4小时，按照一个3k张GPU的集群计算，每次失败导致的回滚都将导致大约3w美元的损失\n常见的监控工具和异常分析工具并不能避免网络产生故障，根据实验表明，在NIC到ToR之间每个月大概有0.057%的Link故障率，在ToR交换机每个月的故障率大约是0.051%，即一个LLM训练集群每个月可能会产生1-2次的Crash，5k-60k次的Link故障\nLLM网络架构的建设目标 规模化：达到15K个GPU的规模，未来可以扩展到100K个GPU的规模\n高性能：尽可能小的网络跳数，尽可能使用GPU-GPU直达的连接\n单点故障容错率：在网络拓扑层尽可能改善单点故障的容错率\n3. HPN架构 分为前端网络和后端网络，前端网络主要负责例如管理、接口、存储等网络流量，后端网络负责LLM的训练时的流量\n每个Host包含8个GPU，使用NVLink互联，双向带宽达到400GBps-900GBps\n每个Host包含9个2x200Gbps的网卡，其中一个连接到前端网络，其余的8个与GPU直连，接入后端网络\n每个网卡的2个端口分别连接至不同的ToR网络，这种双ToR设计可以避免单点故障\n4. 双ToR网络 传统数据中心的NIC的两个光缆接入一个交换机成为单ToR设计\n双ToR设计将NIC的两个光缆接口分别接入不同的ToR交换机中\n两个接口配置相同的IP和MAC地址，即使其中一个ToR故障，另外一个依旧可以正常工作\n基于以上，同一个NIC的两个网卡共享相同的Queue Pair Context\n堆叠的双ToR 两个ToR之间强同步，当主ToR的数据平面发生异常但是控制平面正常时，数据流无法经过主ToR进行转发，此时主ToR的控制平面信息则会与副ToR的控制平面信息不一致，在主ToR看来，是副ToR发生异常导致了该不一致，因此主ToR并不会下线，在副ToR看来是主ToR发生了异常，因此但是主ToR并没有下线，因此副ToR无法切换为主ToR，系统为了避免这种不一致的ToR控制信息，副ToR只能被强制下线，由此整条通路都将会失效\n非堆叠的双ToR 堆叠的双ToR失效的主要原因是两个ToR需要强同步。\n两个ToR要设置为相同的MAC地址，同时要确保该MAC地址并没有被任何Host使用\n不同的PortID，使用Offset计算出两个不同的PortID\n5. Tier 1 Segment 在Tier 1，存在128+8个200Gbps的下游端口和60个400Gbps的上游端口，整个交换机的转发能力达到51.2Tbps，8个下游备用端口连接备用的Host\nrail optimized network\n6. Tier 2 Pod 7. Tier 3 Larger Scale 以GPT-3 175B的训练为例，设置TP=8，PP=8，DP=512，使用32K 个GPU的条件下，流量分析如下：\n根据以上分析发现，PP的流量模式最小，因此可以将PP设置为跨Core层（Tier 3）的通信\n8. 独立的前端网络 存储、关系等网络平面\n9. 评估验证 HPN can improve the end-to-end large-scale training (taking up to 2300+ GPUs) performances by 14.9% compared with DCN+ we conduct network layer monitoring and different collective communication operations to show HPN’s network layer performance improvement 网络层的性能 以下测试基于NCCL 2.18.3，使用56个Host（448个GPU）进行All Reduce/All Gather的测试\nAll Reduce性能增长59.3%，All Gather性能增长较小，可能是因为使用了NSLS导致数据可以在NVSwitch中进行聚合的原因\n","permalink":"https://www.zzudongxiang.com/posts/alibaba-hpn/","summary":"\u003cdiv\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eAlibaba High Performance Network (HPN)\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eHPN介绍了一种两层的双平面网络，可以在一个Pod中接入1.5w个GPU，通常需要3层Clos架构的网络才能容纳这么多GPU\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eHPN 提出了一种新的双 ToR 设计，以取代传统数据中心网络中的单 ToR\u003c/span\u003e\u003c/p\u003e\n\u003ch2 id=\"1-贡献与挑战\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1. 贡献与挑战\u003c/span\u003e\u003c/h2\u003e\n\u003ch3 id=\"挑战\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e挑战\u003c/span\u003e\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e\u003cstrong\u003e流量模式\u003c/strong\u003e\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e传统网络无法应对LLM的低熵、周期性、突发的网络特点，传统的数据中心网络一般是高熵的（传统网络中会存在百万条流，但是每条流的利用率特别低，一半小于20%）\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eECMP在传统的数据中心的高熵、低利用率的网络中性能表现较好，但是在LLM训练中并不是最佳的\u003c/span\u003e\u003c/p\u003e\n\u003cimg src=\"images/image-zyhs.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e\u003cstrong\u003e单点故障的敏感性高\u003c/strong\u003e\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eLLM训练是一个同步过程，所有GPU合作完成一系列迭代，任何一个GPU发生故障都有可能导致整个训练过程出现问题\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e对LLM训练影响最大的是与机架顶部（ToR）相关的单点故障，这种故障可能会影响到各种GPU\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e生产统计数据显示，LLM训练中出现的故障造成的损失是一般云计算故障的 20 倍\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"贡献\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e贡献\u003c/span\u003e\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e非堆叠的双层ToR网络，可以在两个交换机之间直接同步，很好的改善了大规模部署的可信度\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e适配最新的51.2Tbps的交换机芯片，可以将1K个GPU部署在Tier 1网络中，使96.3%的训练任务获得高性能的网络\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e我们的实验表明，使用HPN的LLM训练吞吐量比传统数据中心网络高14.9倍\u003c/span\u003e\u003c/p\u003e\n\u003ch2 id=\"2-背景知识\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e2. 背景知识\u003c/span\u003e\u003c/h2\u003e\n\u003ch3 id=\"llm的并行策略\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003eLLM的并行策略\u003c/span\u003e\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e\u003cstrong\u003eDP\u003c/strong\u003e：每次迭代使用All Reduce同步计算梯度数据\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e\u003cstrong\u003ePP\u003c/strong\u003e：每次使用Send/Recv传递中间结果\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e\u003cstrong\u003eTP\u003c/strong\u003e：每次迭代使用All Reduce/All Gather同步输出和对应的梯度\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"llm的流量特征\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003eLLM的流量特征\u003c/span\u003e\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e带宽利用率周期性突发\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e流的数量少\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e传统的数据中心网络不适用于LLM流量模式\u003c/span\u003e\u003c/p\u003e\n\u003ch3 id=\"llm对单点故障的敏感性\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003eLLM对单点故障的敏感性\u003c/span\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eLLM每次的Checkpoint间隔大概在2-4小时，按照一个3k张GPU的集群计算，每次失败导致的回滚都将导致大约3w美元的损失\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e常见的监控工具和异常分析工具并不能避免网络产生故障，根据实验表明，在NIC到ToR之间每个月大概有0.057%的Link故障率，在ToR交换机每个月的故障率大约是0.051%，即一个LLM训练集群每个月可能会产生1-2次的Crash，5k-60k次的Link故障\u003c/span\u003e\u003c/p\u003e\n\u003cimg src=\"images/image-wxuc.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003ch3 id=\"llm网络架构的建设目标\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003eLLM网络架构的建设目标\u003c/span\u003e\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e规模化：达到15K个GPU的规模，未来可以扩展到100K个GPU的规模\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e高性能：尽可能小的网络跳数，尽可能使用GPU-GPU直达的连接\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e单点故障容错率：在网络拓扑层尽可能改善单点故障的容错率\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"3-hpn架构\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e3. HPN架构\u003c/span\u003e\u003c/h2\u003e\n\u003cimg src=\"images/image-xjoy.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e分为前端网络和后端网络，前端网络主要负责例如管理、接口、存储等网络流量，后端网络负责LLM的训练时的流量\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e每个Host包含8个GPU，使用NVLink互联，双向带宽达到400GBps-900GBps\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e每个Host包含9个2x200Gbps的网卡，其中一个连接到前端网络，其余的8个与GPU直连，接入后端网络\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e每个网卡的2个端口分别连接至不同的ToR网络，这种双ToR设计可以避免单点故障\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"4-双tor网络\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e4. 双ToR网络\u003c/span\u003e\u003c/h2\u003e\n\u003cimg src=\"images/image-goji.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e传统数据中心的NIC的两个光缆接入一个交换机成为单ToR设计\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e双ToR设计将NIC的两个光缆接口分别接入不同的ToR交换机中\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e两个接口配置相同的IP和MAC地址，即使其中一个ToR故障，另外一个依旧可以正常工作\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e基于以上，同一个NIC的两个网卡共享相同的Queue Pair Context\u003c/span\u003e\u003c/p\u003e","title":"文献阅读《Alibaba HPN: A Data Center Network for Large Language Model Training》"},{"content":" we survey the current state-of-the-art collective communication libraries (namely xCCL, including NCCL, oneCCL, RCCL, MSCCL, ACCL, and Gloo), with a focus on the industry-led ones for deep learning workloads.\n常见的MPI库：MPICH、MVAPICH、OpenMPI\n其他的非MPI库：OpenSHMEM（Open-source Symmetric Hierarchical MEMory）、UCX（Unified Communication X）、UCC（Unified Collective Communication）\n常见的xCCL库：NVIDIA Collective Communications Library (NCCL)、AMD\u0026rsquo;s ROCm Collective Communication Library (RCCL)、Gloo\n1. 贡献与挑战 挑战 什么让同时代的xCCL比MPI更具有吸引力？\n每种集合通信库的性能特性如何？\n这些xCCL库是如何设计的？是否存在某种共享的设计模式？\n贡献 总结和研究集合通信原语、网络拓扑、算法，为同时代的深度学习训练奠定基础\n讨论这些研究的工业集合通信解决方案以及其细节测试\n对比当前的集合通信库的性能情况\n2. 集合通信原语 Broadcast：常用于将训练数据发送到各个设备上\nAll Reduce：广泛应用于分布式神经网络训练的后向传播阶段\nAll Gather、Scatter、All-to-All、Reduce、Reduce Scatter\n3. 网络拓扑架构 3.1 HyperCube 优点：高度的连接性，不容易发生故障\n缺点：连接过于复杂，不适用于大规模集群系统，导致部署频率低\n3.2 Ring 优点：无论是单向还是双向环，数据流只有一个流动方向，因此不会发生包碰撞；在一个现成的Ring拓扑中可以很容易添加一个节点；不需要中心服务器协调网络连接\n缺点：在最坏的情况下，数据传输需要经过网络中的所有设备，导致数据传输不够灵活；网络中的任意一个节点故障都将会导致整个网络瘫痪；对于传输较小的数据包的情况下，通道的利用率较低，导致带宽碎片化\n3.3 Torus Torus拓扑是Ring拓扑的高纬度抽象\n优点：可以明显的减小网络的直径；在网络中添加一个成员是比较容易的\n缺点：随着维度的增加，网络布线的复杂度也在增加；在给定维度上添加新的节点将会带来更大的通信开销，消息的传递必须经过更多的节点\n为了解决以上问题，有一个新的变种的Torus拓扑叫做folded-torus\n3.4 Fat-Tree 优点：节点之间的平均距离呈对数增长，因为他自身就是一个树状结构；具有递归可扩展性和可分区性，具有多种精心设计的路由算法；具有对称性、规律性、高度连接性\n缺点：分支和根路由之间的带宽需求随着胖树的增长逐渐增加导致其实现成为瓶颈；由于胖树架构的特点，两个叶节点之间数据传输都必须经过叶路由\n3.5 Dragonfly 优点：模块化的设计；节点内通信和节点间通信是解构的；具有很高的扩展性；在大规模集群上保持较少的跳数\n缺点：构建成本较高；很高的路径多样性导致在一些流量模式下网络利用率和吞吐较低\n为了解决以上问题，有一个新的变种的Dragonfly拓扑叫Dragonfly+\n4. 集合通信算法 4.1 Ring All Gather 每个进程发送自己的数据块到Ring数据流的下一个节点，并从Ring数据流的上一个节点接收数据块\n每个进程发送自己上一步接收的数据，然后与上一步的操作相似\n如果一个Ring中存在 p 个节点，则需要 p-1 步即可完成算法，如果数据量的大小为 n 则每一步收发的数据大小为 n/p 算法的总耗时为\n$$T^{All \\ Gather}_{Ring}=(p-1)\\alpha +(\\frac{p-1}{p})n\\beta$$All Reduce All Reduce可以看作Reduce Scatter和All Gather的组合（Reduce Scatter可以使用Pairwise-Exchange算法实现）\n$$\\begin{align} T^{All \\ Reduce}_{Ring}\u0026=T^{Reduce \\ Scatter}_{Pairwise \\ Exchange}+T^{All \\ Gather}_{Ring}\\\\ \u0026=2(p-1) \\alpha + 2n \\beta + n\\gamma-\\frac{1}{p}(2n\\beta+n\\gamma) \\end{align}$$4.2 Binomial Tree Broadcast 序号为 ({\\rm root}+(p/2)) 的节点接收来自 \\rm root 的数据\n上一步接收数据的节点和 \\rm root 节点座位新的 \\rm root 节点重复上一步的动作\n该算法按照递归的方式，总共需要进行 \\lg p 步完成，假设每个节点每一步传输数据的大小为 n 则算法总耗时为：\n$$T^{Broadcast}_{Tree}= (\\lg p)(\\alpha + n \\beta)$$因为算法耗时的对数延迟项，该算法在小数据包（小于12KB）或者节点数量小于8的条件下表现很好\nReduce 需要进行 \\lg p 步完成算法，每步传输的数据量大小为 n 算法的耗时为：\n$$T^{Reduce}_{Tree}=(\\lg p)(\\alpha+n\\beta+n\\gamma)$$与Boradcast相似，在小数据包（小于等于2KB）条件下性能表现很好\n4.3 Recursive Doubling All Gather 每个节点与它的临近节点传输数据\n每个节点和与它相距两个节点的节点传输数据\n每个节点和与它相距四个节点的节点传输数据，并以此类推\n当节点的数量是2的次幂时，所有的数据传输将会在 \\lg p 步完成，第一步每个节点交换的数据量为 n/p ，第二步每个节点交换的数据量为 2n/p ，以此类推，最后一个节点的数据交换量为 (2^{\\lg(p-1)}n)/p 则算法的总耗时为\n$$T^{All \\ Gather}_{Rec-Dbl}=\\lg p \\alpha+(\\frac{p-1}{p})n\\beta$$当节点的数据量是2的次幂时，该算法的性能表现很好，且适用于大多数的场景，但是当节点的数量不是2的次幂时该算法的性能表现较差\nReduce Scatter 算法过程和All Gather相似，在第一步，每个节点计算自己对应的数据块进行保留，不需要交换，因此每个节点传输的数据量为 n-(n/p) ，在第二步中，每个节点自身和上一步中通信的节点保留的数据块不进行交换，每个节点交换的数据量为 (n-(2n/p)) ，因此该算法的总耗时如下，该算法适用于极小的数据包（小于32B）\n$$T^{Reduce \\ Scatter}_{Rec-Dbl}=\\lg p\\alpha+(\\lg p-\\frac{p-1}{p})n\\beta+(\\lg p-\\frac{p-1}{p})n\\gamma$$4.4 Recursive Halving Reduce Scatter 每个节点与距离它为 p/2 的节点进行数据交换，每个节点与对应的节点交换自身数据的一半\n每个节点与距离它为 p/4 的节点进行数据交换，每个节点与对应的节点交换的数据再次减半\n以此按照递归操作\n算法的总耗时为：\n$$T^{Reduce \\ Scatter}_{Rec-Half}=\\lg p\\alpha+(\\frac{p-1}{p})n\\beta+(\\frac{p-1}{p})n\\gamma$$4.5 Pairwise Exchange All Gather Pairwise算法是Mesh算法的分步执行版本，通过合理的规划，将通信分解成多个步骤，每一步只从一个节点接收数据、向一个节点发送数据。比如对于 \\rm rankid 为 i 的节点，第一步从 (i-1) 节点接收数据，向 (i+1) 节点发送数据；第二步从 (i-2) 节点接收数据，向 (i+2) 节点发送数据……以此类推。\n总共需要 p-1 步，每步收发的数据大小为 n/p 则总的通信开销为\n$$T^{All \\ Gather}_{Pairewise}=(p-1)\\alpha+(\\frac{p-1}{p})n\\beta$$5. xCCL 5.1 NCCL Ring 用于实现All-Reduce算法，将数据分成多个块，并且一个一个的在GPU之间进行传输，可以有效的降低GPU的空闲时间，但是当GPU设备的数量增多的时候，延迟将会增加\nDouble Binary Trees 由于Ring算法在GPU数量增加时会导致数据传输延迟的增加，在GPU数量较多时使用该算法可以解决该问题\n5.2 MSCCL Microsoft\nRing 用于实现All-Reduce、Reduce-Scatter、All-Gather算法，MSCCL将多个通道分配到一个逻辑Ring中，通过这种方法，可以实现一对GPU之间不同的点对点通信。根据报文大小的不同，一条通道上的报文数量也不同。这种策略可实现逻辑环在各通道之间的分布，并有效地Overlap点对点操作。\nAll Pairs GPU中通常有三种类型的缓冲区：输入缓冲区、输出缓冲区、临时缓冲区。由于Ring算法不适用于小数据包的场景，因此使用All Pairs算法实现All Reduce算法。All Pairs算法实现All Reduce只需要两步即可，因此在小数据包下的延迟非常低。\nHierarchical 为了实现All Reduce算法，可以使用分层网络，第一步在节点内进行Reduce Scatter，第二步在节点间进行Reduce Scatter，第三步在节点间进行All Gather，第四步在节点内实现All Gather\nTwo Step 主要用于All to All算法在节点间传输大量的小数据包\n5.3 Gloo Meta\nRing 实现方法与标准的Ring相同\nRing-Chunked 在Ring算法的基础上将Buffer分割为多个Chunk以便于在进行本地Reduce操作时可以传输其他的Chunk\nHalving Doubling 在All Reduce算法上Halving Doubling算法的设计与Recursive Halving和Doubling算法相似的，Halving Doubling算法使用两个节点的距离决定通信对。\n在Reduce Scatter阶段使用Doubling算法，每个节点持有一份Reduce的结果；在All Gather阶段，使用Halving算法将每个节点中的Reduce结果收集在一起\nPairwise Exchange Pairwise Exchange算法是简单的Halving Doubling算法，每一步上，节点被分成对，对与对之间通信的信息量相同。在 Gloo 中，Pairwise Exchange 用于基准测试\nBCube BCube算法将节点分割为多个组。首先，它在组内进程之间执行 Reduce-Scatter，在不同组的相应进程之间执行 All-Reduce。其次，每个组在组内执行 All-Gather，以便每个进程最终都能收到缩减结果。\n5.4 ACCL Hybrid 最大化带宽利用率，Hybrid算法将All Reduce算法解耦成一系列的微操作，并消除无意义的微操作。首先在组内使用Ring算法进行Reduce Scatter操作，然后再组间使用Halving Doubling算法进行All Reduce操作，最后在组内使用Ring算法进行All Gather操作\n5.5 oneCCL 英特尔 oneAPI 集合通信库（oneCCL）是一个集合通信库，旨在开发一个单一的标准 API，兼容从 CPU、GPU 到 FPGA 等多种不同类型的硬件加速器，从而轻松加速深度学习训练工作负载。\n5.6 RCCL 6. 集合通信与深度学习 6.1 Meta Workload RMCs（recommendation model classes），Meta为了改善推理和训练的效率开发了一个软硬件结合的Neo智能体，它使用Pytorch作为后端实现的，可以实现高效、大规模的DLRM系统（Deep Learning Recommendation Model），它主要有三个关键技术\n4D并行策略（table-wise parallelism, row-wise parallelism, column-wise parallelism, and data parallelism）主要目的是GPU的负载均衡，最小化开销\n混合内核融合技术将参数更新和嵌入计算融合到同一个CUDA内核中。\n一个新的硬件平台——ZionEX，适配4D并行策略的分布式训练平台\n6.2 Google Workload DistBelief：Dean J, Corrado G S, Monga R, Chen K, Devin M, Le Q V, Mao M Z, Ranzato M A, Senior A, Tucker P, Yang K, Ng A Y. Large scale distributed deep networks. In Proc. the 25th Int. Conf. Neural Information Processing Systems, Dec. 2012, pp.1223–1231.\n6.3 Uber Workload Michelangelo：Scaling machine learning at Uber with Michelangelo. https://www.uber.com/blog/scaling-michelangelo, Jan. 2023.\n6.4 Amazon Workload MiCS：Zhang Z, Zheng S, Wang Y S et al. MiCS: Near-linear scaling for training gigantic model on public cloud. Proceedings of the VLDB Endowment, 2022, 16(1): 37–50. DOI: 10.14778/3561261.3561265.\nZeRO：Rajbhandari S, Rasley J, Ruwase O, He Y X. ZeRO: Memory optimizations toward training trillion parameter models. In Proc. the 2020 SC, Nov. 2020.\n7. 实验 7.1 实验条件 实验设备：4个SDSC Expanse cluster\n测试负载：Meta’s PARAM、NCCL Test、OSU MPI Micro-Benchmarks\n测试对象：NCCL、Gloo、MSCCL、CUDA-Aware MPI by MPICH、UCX\n测试环境：Python 3.7、Pytorch 1.13、CUDA 11.6、NCCL 2.14.3、MSCCL 0.7.3、MPICH v4.0.2、UCX v1.13.1\n","permalink":"https://www.zzudongxiang.com/posts/xccl-survey/","summary":"\u003cdiv\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003ewe survey the current state-of-the-art collective communication libraries (namely \u003cstrong\u003exCCL\u003c/strong\u003e, including NCCL, oneCCL, RCCL, MSCCL, ACCL, and Gloo), with a focus on the industry-led ones for deep learning workloads.\u003c/span\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e常见的MPI库：MPICH、MVAPICH、OpenMPI\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e其他的非MPI库：OpenSHMEM（Open-source Symmetric Hierarchical MEMory）、UCX（Unified Communication X）、UCC（Unified Collective Communication）\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e常见的xCCL库：NVIDIA Collective Communications Library (NCCL)、AMD\u0026rsquo;s ROCm Collective Communication Library (RCCL)、Gloo\u003c/span\u003e\u003c/p\u003e\n\u003ch2 id=\"1-贡献与挑战\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1. 贡献与挑战\u003c/span\u003e\u003c/h2\u003e\n\u003ch3 id=\"挑战\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e挑战\u003c/span\u003e\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e什么让同时代的xCCL比MPI更具有吸引力？\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e每种集合通信库的性能特性如何？\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e这些xCCL库是如何设计的？是否存在某种共享的设计模式？\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"贡献\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e贡献\u003c/span\u003e\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e总结和研究集合通信原语、网络拓扑、算法，为同时代的深度学习训练奠定基础\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e讨论这些研究的工业集合通信解决方案以及其细节测试\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e对比当前的集合通信库的性能情况\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-集合通信原语\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e2. 集合通信原语\u003c/span\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eBroadcast：常用于将训练数据发送到各个设备上\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eAll Reduce：广泛应用于分布式神经网络训练的后向传播阶段\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eAll Gather、Scatter、All-to-All、Reduce、Reduce Scatter\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cimg src=\"images/image-bvtn.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003ch2 id=\"3-网络拓扑架构\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e3. 网络拓扑架构\u003c/span\u003e\u003c/h2\u003e\n\u003ch3 id=\"31-hypercube\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e3.1 HyperCube\u003c/span\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e优点：高度的连接性，不容易发生故障\u003c/span\u003e\u003c/p\u003e","title":"文献阅读《xCCL: A Survey of Industry-Led Collective Communication Libraries for Deep Learning》"},{"content":" 《ASTRA-SIM: Enabling SW/HW co-design exploration for distributed DL training platforms》 1. 文章简介 1.1 摘要 现代深度学习系统主要依靠基于高性能加速器（如 TPU、GPU）的硬件平台进行分布式训练。目前的例子包括谷歌的云 TPU 和 Facebook 的 Zion。DNN 训练涉及 DNN 模型架构、并行化策略、调度策略、集体通信算法、网络拓扑和终端加速器之间复杂的相互作用。随着人工智能/ML 模型的创新不断加速发展，需要一种全面的方法来理解和驾驭未来系统中复杂的 SW/HW 设计空间，以支持未来 DNN 模型的高效训练。在这项工作中，我们做出了以下贡献：(i) 为分层扩展结构上的分布式训练建立了 SW/HW 设计空间；(ii) 开发了一个用于导航设计空间的网络模拟器；(iii) 展示了算法拓扑协同设计加速端到端训练的前景。\n1.2 研究动机 对模型架构、并行策略、调度算法、集合通信、网络拓扑、终端算力的仿真\n大规模并行训练成本高，在实际部署和训练之前，需要一个仿真工具进行评估\n1.3 主要贡献 为分层加速器结构设计空间探索建立 SW/HW 设计空间，并确定扩展 DL 工作负载的关键瓶颈\n开发名为 ASTRASIM 的端到端网络模拟器，用于评估设计空间的各个方面\n使用 ASTRA-SIM 对 alltoall 和 Torus 拓扑的 all-reduce 和 all-to-all 集合的一维、二维和三维拓扑进行全面分析\n2. 实现方法 3. 实验结果 实验参数\n这项工作介绍了一种名为 ASTRA-SIM 的模拟器，用于阐述和浏览分布式 DL 训练平台的硬件/软件设计空间。我们重点关注分级放大结构上集体通信算法的详细建模，并实现端到端网络仿真。\n《ASTRA-sim2.0: Modeling Hierarchical Networks and Disaggregated Systems for Large-model Training at Scale》 1. 文章简介 1.1 摘要 由于深度学习模型和输入数据正以前所未有的速度扩展，因此不可避免地要转向分布式训练平台，以适应模型并提高训练吞吐量。最先进的方法和技术，如晶圆级节点、多维网络拓扑结构、分解存储器系统和并行化策略，已被新兴的分布式训练系统积极采用。这导致分布式训练的 SW/HW 协同设计堆栈非常复杂，因此需要建模/仿真基础设施来探索设计空间。在本文中，我们扩展了开源的 ASTRA-sim 基础设施，并赋予其对最先进的和新兴的分布式培训模型和平台进行建模的能力。更具体地说，(i) 我们通过基于图的训练环路实现，使 ASTRA-sim 能够支持任意模型并行化策略；(ii) 我们实现了可参数化的多维异构拓扑生成基础架构，该基础架构具有分析性能估算，能够大规模模拟目标系统；(iii) 我们增强了内存系统建模，以支持网络内集体通信和分解内存系统的精确建模。利用这些功能，我们针对新兴的分布式模型和平台进行了全面的案例研究。这种基础架构可让系统设计人员迅速穿越复杂的协同设计堆栈，并在设计和部署大规模分布式训练平台时提供有意义的见解。\n1.2 研究动机 ASTRA-sim v1.0对限制了它对任意并行策略、网络和内存模型的支持，它在设计和实现的时候并没有针对现有的DP、MP等策略\n目前现有的网络大多是分层的复杂网络拓扑结构\nASTRA-sim v1.0不支持对分布式内存仿真的内容\n1.3 主要贡献 开源的ASTRA-sim仿真软件\n可以支持任意模型的并行策略，ASTRA-sim是基于图实现的\n可参数化的基础架构\n构建内存模拟系统\nASTRA-sim支持任意并行策略\nASTRA-sim支持分层的网络架构\nASTRA-sim支持内存建模\n2. 实现方法 基于图的执行引擎，支持Pytorch、Tensorflow、FlexFlow等框架\n多维度网络拓扑构建，支持分层网络构建\nAnalytical的网络后端\n添加内存模型可以支持本地内存、远程内存、交换机内部集合通信的建模\n3. 实验结果 调度的影响、Wafer规模的影响\n分布式内存的影响\n","permalink":"https://www.zzudongxiang.com/posts/astra-sim/","summary":"\u003cdiv\u003e\n\u003ch1 id=\"astra-sim-enabling-swhw-co-design-exploration-for-distributed-dl-training-platforms\"\u003e《ASTRA-SIM: Enabling SW/HW co-design exploration for distributed DL training platforms》\u003c/h1\u003e\n\u003ch2 id=\"1-文章简介\"\u003e1. 文章简介\u003c/h2\u003e\n\u003ch3 id=\"11-摘要\"\u003e1.1 摘要\u003c/h3\u003e\n\u003cp\u003e现代深度学习系统主要依靠基于高性能加速器（如 TPU、GPU）的硬件平台进行分布式训练。目前的例子包括谷歌的云 TPU 和 Facebook 的 Zion。DNN 训练涉及 DNN 模型架构、并行化策略、调度策略、集体通信算法、网络拓扑和终端加速器之间复杂的相互作用。随着人工智能/ML 模型的创新不断加速发展，需要一种全面的方法来理解和驾驭未来系统中复杂的 SW/HW 设计空间，以支持未来 DNN 模型的高效训练。在这项工作中，我们做出了以下贡献：(i) 为分层扩展结构上的分布式训练建立了 SW/HW 设计空间；(ii) 开发了一个用于导航设计空间的网络模拟器；(iii) 展示了算法拓扑协同设计加速端到端训练的前景。\u003c/p\u003e\n\u003ch3 id=\"12-研究动机\"\u003e1.2 研究动机\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e对模型架构、并行策略、调度算法、集合通信、网络拓扑、终端算力的仿真\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e大规模并行训练成本高，在实际部署和训练之前，需要一个仿真工具进行评估\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"13-主要贡献\"\u003e1.3 主要贡献\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e为分层加速器结构设计空间探索建立 SW/HW 设计空间，并确定扩展 DL 工作负载的关键瓶颈\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e开发名为 ASTRASIM 的端到端网络模拟器，用于评估设计空间的各个方面\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e使用 ASTRA-SIM 对 alltoall 和 Torus 拓扑的 all-reduce 和 all-to-all 集合的一维、二维和三维拓扑进行全面分析\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-实现方法\"\u003e2. 实现方法\u003c/h2\u003e\n\u003cimg src=\"images/image-oiub.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003ch2 id=\"3-实验结果\"\u003e3. 实验结果\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e实验参数\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan style=\"font-size: 16px; color: rgb(91, 70, 155)\"\u003e\u003cimg src=\"images/image-spfp.png\" style=\"display: inline-block;width:35.0%\" /\u003e\u003c/span\u003e\u003c/p\u003e","title":"《ASTRA-sim 系列两篇》"},{"content":" 1. 文章简介 1.1 摘要 基准测试和协同设计对于推动 ML 模型、ML 软件和下一代硬件的优化和创新至关重要。全工作量基准（如 MLPerf）在实现不同软件和硬件堆栈之间的公平比较方面发挥着至关重要的作用，尤其是在系统完全设计和部署之后。然而，人工智能创新的步伐要求模拟器和仿真器采用更加敏捷的方法来创建和使用基准，以实现未来的系统协同设计。我们提出了 Chakra，这是一种开放式图模式，用于标准化工作负载规范，捕捉关键操作和依赖关系，也称为执行跟踪（ET）。此外，我们还提出了一套互补的工具/功能，使各种模拟器、仿真器和基准能够收集、生成和采用 Chakra ET。例如，我们使用生成式人工智能模型学习数千种 Chakra ET 的潜在统计属性，并使用这些模型合成 Chakra ET。这些合成的 ET 可以混淆关键的专有信息，还可以针对未来的假设场景进行设计。举例来说，我们展示了一个端到端的概念验证，它能将 PyTorch ET 转换为 Chakra ET，并以此驱动一个开源训练系统模拟器（ASTRA-sim）。我们的最终目标是建立一个充满活力的全行业敏捷基准和工具生态系统，以推动未来的人工智能系统协同设计。\n1.2 研究动机 Full Workload Benchmarks对于评价分布式训练的性能虽然非常重要，但是需要更加敏捷的方式\n评价分布式训练的软硬件联合设计的效果\n不同的AI/ML模型通常由不同的公司在不同的平台上构建，通常不能提供公开模型的细节\n缺少在不同的组织之间交换ML模型ET的统一架构\n缺少完善的性能评估工具链\n目前的方法缺乏合成ET的能力\n以Pytorch为例，可以使用Execution Graph Observer获取直接的ET，但是这种方法得到的结果受真实的系统的限制（例如NPU数量，计算时间，网络延迟等），使用合成的ET可以避免这些限制\n1.3 主要贡献 捕捉相关执行和依赖信息的 Chakra ET\n可视化器、转换器和模拟器等开源工具链\n人工智能生成模型的ET合成\n2. 实现方法 2.1 设计需求 应该包含内存访问、计算负载、网络通信、并行策略\n应该最小化且可扩展\n应该从性能建模的角度对 ML 执行的各个方面进行建模\n应该能显示不同执行阶段的ET，且与设备解耦\n2.2 实现方案 2.2.1 ET的表示 A. Chakra Node type的值范围\nINVALID 字段的初始值，用于忽略非关键节点\nMEM_LOAD、MEM_STORE\nCOMP\nCOMM_SEND、COMM_RECV、COMM_COLL\nB. Chakra Attribute type的值范围\n6种：float, int, string, and their repetitions 2.2.2 ET的收集 Pre-Execution vs. Post-Execution 确定适当的跟踪收集级别是一项关键的设计选择。一般来说，跟踪收集级别可分为执行前和执行后两种。\nPre-Execution是指ML模型尚未明确优化或与特定系统配置（如引擎、内存或网络）绑定的阶段\nPre-Execution段收集跟踪，可以对不同系统的性能进行预测，因为它与特定配置无关\nPost-Execution阶段涉及在实际系统上优化和执行 ML 模型\nPost-Execution阶段收集的ET与运行模型的实际系统紧密相关，在性能预测方面的实用性受限制\nChakra 模式旨在适应任何执行阶段。然而，如何从真实系统中收集迹线而不与之紧密绑定仍是一个未决问题。\n支持按照分布式策略分解成多个ET，并部署到多个NPU上执行\n也可以支持从多个分布式的ET文件合并成一个单个的Master Trace，这个过程是无损可逆的\n在收集ET时，由于不同的框架具有不同的ET格式，因此可以使用ET转换脚本转为标准的ET格式\n3. 实验结果 实验条件\nThe 2D-torus is an 8×8 2D-torus topology with 64 NPUs and a link bandwidth of 62GB/s.\nthe DGX2 is a hierarchical network topology connected with switches, with network bandwidths for the first and second dimensions set to 600GB/s and 37.5GB/s\n不同模型和并行数量的仿真结果\net.al.\n4. 其他内容 假定存在一个使用Pytorch编写的ML代码，生成ET的步骤如下：\n在PyTorch中启用Execution Graph Observer，这是一个用于收集模型执行时的详细信息的工具。它不需要对ML模型进行侵入性修改。\n运行PyTorch模型进行训练。在训练过程中，Execution Graph Observer将捕获关键的操作和依赖关系，生成原始的执行跟踪数据。\n将PyTorch生成的原始执行跟踪转换为Chakra ET格式。这可能涉及到使用ET转换器（ET Converter），它能够读取PyTorch的JSON格式跟踪数据，并将其转换成Chakra定义的标准化ET格式。\n利用Chakra提供的工具链，如执行跟踪可视化器（Execution Trace Visualizer）和时间线可视化器（Timeline Visualizer），来分析和理解ET。\n使用收集到的Chakra ETs作为训练数据，训练一个生成性AI模型。这个模型将学习ETs中的统计特性和模式。\n使用训练好的生成性AI模型来合成新的ETs。这些合成的ETs可以用于模拟不同的系统配置和未来场景，同时保护原始模型的知识产权。\n将合成的ETs输入到性能模型或仿真器（如ASTRA-sim）中，以评估不同硬件配置下的性能。\n分析仿真结果，识别性能瓶颈和优化机会。根据这些信息调整模型结构或系统配置，以提高性能。\n","permalink":"https://www.zzudongxiang.com/posts/chakra-benchmarking/","summary":"\u003cdiv\u003e\n\u003ch2 id=\"1-文章简介\"\u003e1. 文章简介\u003c/h2\u003e\n\u003ch3 id=\"11-摘要\"\u003e1.1 摘要\u003c/h3\u003e\n\u003cp\u003e基准测试和协同设计对于推动 ML 模型、ML 软件和下一代硬件的优化和创新至关重要。全工作量基准（如 MLPerf）在实现不同软件和硬件堆栈之间的公平比较方面发挥着至关重要的作用，尤其是在系统完全设计和部署之后。然而，人工智能创新的步伐要求模拟器和仿真器采用更加敏捷的方法来创建和使用基准，以实现未来的系统协同设计。我们提出了 Chakra，这是一种开放式图模式，用于标准化工作负载规范，捕捉关键操作和依赖关系，也称为执行跟踪（ET）。此外，我们还提出了一套互补的工具/功能，使各种模拟器、仿真器和基准能够收集、生成和采用 Chakra ET。例如，我们使用生成式人工智能模型学习数千种 Chakra ET 的潜在统计属性，并使用这些模型合成 Chakra ET。这些合成的 ET 可以混淆关键的专有信息，还可以针对未来的假设场景进行设计。举例来说，我们展示了一个端到端的概念验证，它能将 PyTorch ET 转换为 Chakra ET，并以此驱动一个开源训练系统模拟器（ASTRA-sim）。我们的最终目标是建立一个充满活力的全行业敏捷基准和工具生态系统，以推动未来的人工智能系统协同设计。\u003c/p\u003e\n\u003ch3 id=\"12-研究动机\"\u003e1.2 研究动机\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eFull Workload Benchmarks对于评价分布式训练的性能虽然非常重要，但是需要更加敏捷的方式\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e评价分布式训练的软硬件联合设计的效果\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e不同的AI/ML模型通常由不同的公司在不同的平台上构建，通常不能提供公开模型的细节\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e缺少在不同的组织之间交换ML模型ET的统一架构\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e缺少完善的性能评估工具链\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e目前的方法缺乏合成ET的能力\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e以Pytorch为例，可以使用Execution Graph Observer获取直接的ET，但是这种方法得到的结果受真实的系统的限制（例如NPU数量，计算时间，网络延迟等），使用合成的ET可以避免这些限制\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"13-主要贡献\"\u003e1.3 主要贡献\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e捕捉相关执行和依赖信息的 Chakra ET\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e可视化器、转换器和模拟器等开源工具链\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e人工智能生成模型的ET合成\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-实现方法\"\u003e2. 实现方法\u003c/h2\u003e\n\u003ch3 id=\"21-设计需求\"\u003e2.1 设计需求\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e应该包含内存访问、计算负载、网络通信、并行策略\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e应该最小化且可扩展\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e应该从性能建模的角度对 ML 执行的各个方面进行建模\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e应该能显示不同执行阶段的ET，且与设备解耦\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"22-实现方案\"\u003e2.2 实现方案\u003c/h3\u003e\n\u003ch4 id=\"221-et的表示\"\u003e2.2.1 ET的表示\u003c/h4\u003e\n\u003ch5 id=\"a-chakra-node\"\u003eA. Chakra Node\u003c/h5\u003e\n\u003cimg src=\"images/image-20240615162533121.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003cp\u003e\u003cstrong\u003etype的值范围\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eINVALID\u003c/strong\u003e 字段的初始值，用于忽略非关键节点\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eMEM_LOAD、MEM_STORE\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eCOMP\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eCOMM_SEND、COMM_RECV、COMM_COLL\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch5 id=\"b-chakra-attribute\"\u003eB. Chakra Attribute\u003c/h5\u003e\n\u003cimg src=\"images/image-20240615162606441.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003cp\u003e\u003cstrong\u003etype的值范围\u003c/strong\u003e\u003c/p\u003e","title":"文献阅读《Chakra: Advancing performance benchmarking and co-design using standardized execution traces》"},{"content":" 1. 内容简介 1.1 摘要 拥塞控制（CC）是高速网络实现超低延迟、高带宽和网络稳定性的关键。根据多年运营大规模高速 RDMA 网络的经验，我们发现现有的高速拥塞控制方案在实现这些目标方面存在固有的局限性。在本文中，我们提出了 HPCC（高精度拥塞控制），一种能同时实现上述三个目标的新型高速拥塞控制机制。HPCC 利用网内遥测（INT）获取精确的链路负载信息，并精确控制流量。通过解决拥塞期间 INT 信息延迟和对 INT 信息反应过度等难题，HPCC 可以在避免拥塞的同时快速收敛以利用空闲带宽，并能保持近乎零的网内队列以实现超低延迟。HPCC 在硬件上的部署也是公平、简单的。我们利用商品可编程网卡和交换机实现了 HPCC。在我们的评估中，与 DCQCN 和 TIMELY 相比，HPCC 可将流量完成时间缩短达 95%，即使在大规模数据交换的情况下也几乎不会造成拥塞。\n1.2 研究动机 FPC风暴：网络上一旦出现阻塞，根据RoCEv2协议会发送FPC暂停帧，进而导致网络停摆\n超大延迟：由于阻塞网络队列的影响，神经网络训练时的延迟大到超乎想象\n收敛速度慢：由于依赖的Feedback信息颗粒度不够，导致处理大规模阻塞事件时收敛慢\n不可避免的缓存队列：由于DCQCN和TIMELY等都依赖队列信息的感知，因此无法避免延迟大的问题\n复杂的调参：不同的应用有不同的流量模式，不同的环境有不同的拓扑、链接速度、交换机缓冲区大小等，因此在不同环境下部署不同应用时都要对参数进行微调\n1.3 主要贡献 HPCC的发送端可以快速提高发送速率以提高带宽利用率，同时可以快速降低发送速率，以避免产生阻塞\nHPCC的发送端可以快速的调整发送速率以确保每条连接的输入速率略小于其带宽能力\n一旦发送速率在路由中精确计算出结果，HPCC只需要3个独立的参数就可以调整其效率和公平性\n2. 实现方法 Sender发送输入给Receiver，数据在经过中间的Switch时会被Switch添加一些INT数据作为metadata，Receiver在ACK时把这些metadata传递给Sender，然后Sender根据这些INT数据调整自己的发送速率\nSender通过发送窗口限制在途数据的数量\n基于在途数据量的阻塞控制信号和控制策略\n快速响应而不是过响应\n实现方法，FPGA网卡\n3. 实验结果 小规模测试+大规模NS3仿真\n测试条件 - 网络拓扑\nThe testbed topology mimics a small scale RDMA PoD in our production. The testbed includes one Agg switch and four ToRs (ToR1-ToR4) connected via four 100Gbps links. There are 32 servers in total and each server has two 25Gbps NICs. 16 servers are connected to ToR1 and ToR2 via two uplinks, and the other 16 servers are connected to ToR3 and ToR4. The base RTT is 5.4μs within a rack and 8.5μs cross racks.\nThe topology in the NS3 simulations is a FatTree. There are 16 Core switches, 20 Agg switches, 20 ToRs and 320 servers (16 in each rack), and each server has a single 100Gbps NIC connected to a single ToR. The capacity of each link between Core and Agg switches, Agg switches and ToRs are all 400Gbps. All links have a 1μs propagation delay, which gives a 12μs maximum base RTT. The switch buffer size is 32MB which is derived from real device configurations. The whole network is a single RDMA domain.\n测试条件 - 流量负载\nWe use widely accepted and public available data center traffic traces, WebSearch and FB_Hadoop in both testbed experiments and simulations.\nWe adjust the flow generation rates to set the average link loads to 30% and 50% respectively. We also create some simple artificial traffic loads to evaluate the microbenchmarks of HPCC.\n测试条件 - 对比方法\nDCQCN\nTIMELY\n实验结果\n(a) vs. (b) 在Long Flow条件下，HPCC的吞吐量优于DCQCN，Buffer Size远小于DCQCN\n(c) vs. (d) 在Incast流量下，HPCC的吞吐量与DCQCN相似\n(e) HPCC的延迟远小于（10倍）DCQCN\n(f) HPCC的Buffer Size远小于DCQCN\n(g) vs. (h) HPCC的Fairness略好于DCQCN，带宽抖动小于DCQCN\n","permalink":"https://www.zzudongxiang.com/posts/hpcc-congestion-control/","summary":"\u003cdiv\u003e\n\u003ch2 id=\"1-内容简介\"\u003e1. 内容简介\u003c/h2\u003e\n\u003ch3 id=\"11-摘要\"\u003e1.1 摘要\u003c/h3\u003e\n\u003cp\u003e拥塞控制（CC）是高速网络实现超低延迟、高带宽和网络稳定性的关键。根据多年运营大规模高速 RDMA 网络的经验，我们发现现有的高速拥塞控制方案在实现这些目标方面存在固有的局限性。在本文中，我们提出了 HPCC（高精度拥塞控制），一种能同时实现上述三个目标的新型高速拥塞控制机制。HPCC 利用网内遥测（INT）获取精确的链路负载信息，并精确控制流量。通过解决拥塞期间 INT 信息延迟和对 INT 信息反应过度等难题，HPCC 可以在避免拥塞的同时快速收敛以利用空闲带宽，并能保持近乎零的网内队列以实现超低延迟。HPCC 在硬件上的部署也是公平、简单的。我们利用商品可编程网卡和交换机实现了 HPCC。在我们的评估中，与 DCQCN 和 TIMELY 相比，HPCC 可将流量完成时间缩短达 95%，即使在大规模数据交换的情况下也几乎不会造成拥塞。\u003c/p\u003e\n\u003ch3 id=\"12-研究动机\"\u003e1.2 研究动机\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eFPC风暴：网络上一旦出现阻塞，根据RoCEv2协议会发送FPC暂停帧，进而导致网络停摆\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e超大延迟：由于阻塞网络队列的影响，神经网络训练时的延迟大到超乎想象\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e收敛速度慢：由于依赖的Feedback信息颗粒度不够，导致处理大规模阻塞事件时收敛慢\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e不可避免的缓存队列：由于DCQCN和TIMELY等都依赖队列信息的感知，因此无法避免延迟大的问题\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e复杂的调参：不同的应用有不同的流量模式，不同的环境有不同的拓扑、链接速度、交换机缓冲区大小等，因此在不同环境下部署不同应用时都要对参数进行微调\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"13-主要贡献\"\u003e1.3 主要贡献\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eHPCC的发送端可以快速提高发送速率以提高带宽利用率，同时可以快速降低发送速率，以避免产生阻塞\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eHPCC的发送端可以快速的调整发送速率以确保每条连接的输入速率略小于其带宽能力\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e一旦发送速率在路由中精确计算出结果，HPCC只需要3个独立的参数就可以调整其效率和公平性\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-实现方法\"\u003e2. 实现方法\u003c/h2\u003e\n\u003cimg src=\"images/image-20240612113350024.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003cp\u003eSender发送输入给Receiver，数据在经过中间的Switch时会被Switch添加一些INT数据作为metadata，Receiver在ACK时把这些metadata传递给Sender，然后Sender根据这些INT数据调整自己的发送速率\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eSender通过发送窗口限制在途数据的数量\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e基于在途数据量的阻塞控制信号和控制策略\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e快速响应而不是过响应\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003e实现方法，FPGA网卡\u003c/strong\u003e\u003c/p\u003e\n\u003cimg src=\"images/image-20240612113825169.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003ch2 id=\"3-实验结果\"\u003e3. 实验结果\u003c/h2\u003e\n\u003cp\u003e小规模测试+大规模NS3仿真\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e测试条件 - 网络拓扑\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eThe testbed topology\u003c/strong\u003e mimics a small scale RDMA PoD in our production. The testbed includes one Agg switch and four ToRs (ToR1-ToR4) connected via four 100Gbps links. There are 32 servers in total and each server has two 25Gbps NICs. 16 servers are connected to ToR1 and ToR2 via two uplinks, and the other 16 servers are connected to ToR3 and ToR4. The base RTT is 5.4μs within a rack and 8.5μs cross racks.\u003c/p\u003e","title":"文献阅读《HPCC: high precision congestion control》"},{"content":" 1. 内容简介 1.1 摘要 聚合以太网（RoCE）上的 RDMA 协议因其与传统以太网结构的兼容性而对数据中心网络产生了巨大的吸引力。然而，RDMA 协议只有在（几乎）无损网络上才有效，这就强调了拥塞控制在 RoCE 网络中的重要作用。遗憾的是，基于优先级流量控制（PFC）的本地 RoCE 拥塞控制方案存在许多缺点，如不公平、头线阻塞和死锁。因此，近年来人们提出了许多为 RoCE 网络提供额外拥塞控制的方案，以尽量减少 PFC 的缺点。不过，这些方案都是针对一般数据中心环境提出的。与使用商品硬件构建并运行通用工作负载的普通数据中心不同，高性能分布式培训平台部署了高端加速器和网络组件，并使用集体（All-Reduce、All-To-All）通信库专门运行培训工作负载。此外，这些平台通常有一个专用网络，将其通信流量与数据中心的其他流量分开。可扩展的拓扑感知集体算法本质上就是为了避免同播模式并优化流量平衡而设计的。由于这些显著特点，我们有必要重新审视以前提出的通用数据中心环境拥塞控制方案。在本文中，我们深入分析了在分布式培训平台上运行时，一些最先进的 RoCE 拥塞控制方案（DCQCN、DCTCP、TIMELY 和 HPCC）与 PFC 的对比。我们的研究结果表明，以前提出的 RoCE 拥塞控制方案对培训工作负载的端到端性能影响甚微，因此有必要根据分布式培训平台和工作负载的特点设计一种优化的、低开销的拥塞控制方案。\n1.2 研究动机 标准的RoCE协议使用FPC协议控制阻塞，但是会带来不平衡、队头阻塞和死锁的问题\n传统的基于RoCE的阻塞控制算法是基于通用的数据中心构建的\n之前的阻塞控制协议（DCQCN、TIMELY、HPCC等）并不适用于DNN训练的场景\n1.3 主要贡献 第一个在DNN分布式训练任务上进行阻塞控制方案评估的工作\n使用ASTRA-sim和NS3使用不同的阻塞控制方案进行仿真验证\n对每个现成的阻塞控制方案进行详细的分析，包括集合通信和DNN训练负载等\n不同的最先进 RoCE 拥塞控制方案对端到端培训性能影响甚微\n我们为设计一种针对分布式训练的优化且低开销的拥塞控制方案指明了方向\n2. 实现方法 使用ASTRA-sim仿真 网络拓扑 系统参数 3. 实验结果 3.1 Single-switch Incast micro-benchmark FPC only 队列快速满载，随后网络被反复暂停并重复这一过程\nDCQCN在设置参数时确保没有FPC触发，且带宽率用率较高\nDCTCP、TIMELY等在没有触发FPC帧的条件下\n3.2 Single-switch Collectives Micro-benchmark 在8-128个GPU条件下进行All-To-All和All-Reduce集合通信\n在集合通信条件下不存在阻塞，所以没有阻塞控制算法对其无效\n3.3 Two-level CLOS topology 在TOR网络下的All-To-All集合通信算法对交换机缓存的影响\n除了TIMELY阻塞控制算法外，其他算法在集合通信的条件下都有相似的表现\n怀疑是TIMELY的参数设置不佳导致TIMELY算法的带宽利用率较低\n3.4 Real Workload: DLRM Results 不同的阻塞控制算法对其影响的程度小于4%\nTIMELY的效果并没有像仿真的时候效果那么差\n在真实的单任务训练过程中或者在NS3仿真时由于集合通信算法的加持下：\n是否几乎没有出现网络阻塞的情况，进而不同的阻塞控制算法几乎没有太大的影响？\n是否已经达到了理想的带宽利用率，所以阻塞控制算法收益不大？ ","permalink":"https://www.zzudongxiang.com/posts/roce-congestion-control/","summary":"\u003cdiv\u003e\n\u003ch2 id=\"1-内容简介\"\u003e1. 内容简介\u003c/h2\u003e\n\u003ch3 id=\"11-摘要\"\u003e1.1 摘要\u003c/h3\u003e\n\u003cp\u003e聚合以太网（RoCE）上的 RDMA 协议因其与传统以太网结构的兼容性而对数据中心网络产生了巨大的吸引力。然而，RDMA 协议只有在（几乎）无损网络上才有效，这就强调了拥塞控制在 RoCE 网络中的重要作用。遗憾的是，基于优先级流量控制（PFC）的本地 RoCE 拥塞控制方案存在许多缺点，如不公平、头线阻塞和死锁。因此，近年来人们提出了许多为 RoCE 网络提供额外拥塞控制的方案，以尽量减少 PFC 的缺点。不过，这些方案都是针对一般数据中心环境提出的。与使用商品硬件构建并运行通用工作负载的普通数据中心不同，高性能分布式培训平台部署了高端加速器和网络组件，并使用集体（All-Reduce、All-To-All）通信库专门运行培训工作负载。此外，这些平台通常有一个专用网络，将其通信流量与数据中心的其他流量分开。可扩展的拓扑感知集体算法本质上就是为了避免同播模式并优化流量平衡而设计的。由于这些显著特点，我们有必要重新审视以前提出的通用数据中心环境拥塞控制方案。在本文中，我们深入分析了在分布式培训平台上运行时，一些最先进的 RoCE 拥塞控制方案（DCQCN、DCTCP、TIMELY 和 HPCC）与 PFC 的对比。我们的研究结果表明，以前提出的 RoCE 拥塞控制方案对培训工作负载的端到端性能影响甚微，因此有必要根据分布式培训平台和工作负载的特点设计一种优化的、低开销的拥塞控制方案。\u003c/p\u003e\n\u003ch3 id=\"12-研究动机\"\u003e1.2 研究动机\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e标准的RoCE协议使用FPC协议控制阻塞，但是会带来不平衡、队头阻塞和死锁的问题\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e传统的基于RoCE的阻塞控制算法是基于通用的数据中心构建的\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e之前的阻塞控制协议（DCQCN、TIMELY、HPCC等）并不适用于DNN训练的场景\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"13-主要贡献\"\u003e1.3 主要贡献\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e第一个在DNN分布式训练任务上进行阻塞控制方案评估的工作\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e使用ASTRA-sim和NS3使用不同的阻塞控制方案进行仿真验证\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e对每个现成的阻塞控制方案进行详细的分析，包括集合通信和DNN训练负载等\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e不同的最先进 RoCE 拥塞控制方案对端到端培训性能影响甚微\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e我们为设计一种针对分布式训练的优化且低开销的拥塞控制方案指明了方向\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-实现方法\"\u003e2. 实现方法\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e使用ASTRA-sim仿真\u003c/li\u003e\n\u003c/ul\u003e\n\u003cimg src=\"images/image-20240612162335878.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003cul\u003e\n\u003cli\u003e网络拓扑\u003c/li\u003e\n\u003c/ul\u003e\n\u003cimg src=\"images/image-20240612162354414.png\" style=\"display: inline-block;width:65.0%\" /\u003e\n\u003cul\u003e\n\u003cli\u003e系统参数\u003c/li\u003e\n\u003c/ul\u003e\n\u003cimg src=\"images/image-20240612162411148.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003ch2 id=\"3-实验结果\"\u003e3. 实验结果\u003c/h2\u003e\n\u003ch3 id=\"31-single-switch-incast-micro-benchmark\"\u003e3.1 Single-switch Incast micro-benchmark\u003c/h3\u003e\n\u003cimg src=\"images/image-20240612162627263.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eFPC only 队列快速满载，随后网络被反复暂停并重复这一过程\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eDCQCN在设置参数时确保没有FPC触发，且带宽率用率较高\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eDCTCP、TIMELY等在没有触发FPC帧的条件下\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"32-single-switch-collectives-micro-benchmark\"\u003e3.2 Single-switch Collectives Micro-benchmark\u003c/h3\u003e\n\u003cimg src=\"images/image-20240612163247646.png\" style=\"display: inline-block;width:75.0%\" /\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e在8-128个GPU条件下进行All-To-All和All-Reduce集合通信\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e在集合通信条件下不存在阻塞，所以没有阻塞控制算法对其无效\u003c/p\u003e","title":"文献阅读《Impact of RoCE congestion control policies on distributed training of dnns》"},{"content":" 1. 文章简介 1.1 摘要 部署在数据中心网络（DCN）上的应用日益复杂和先进，对 DCN 的新功能和更高性能提出了更高要求。这就产生了许多设计，以应对成本、性能、可靠性、可扩展性、安全性和能源等各种挑战。设计人员经常面临的一个主要挑战是如何实现他们提出的设计或实现现有设计进行比较。虽然原型设计是更好的选择，但它有一定的局限性，而且非常复杂和昂贵。因此，仿真被认为是原型设计的替代方案。\n本文介绍了使用网络Network Simulator 3（NS3）实现 DCN 的各种架构并研究其性能的案例研究。我们提供的信息包括最流行的 DCN 设计的实现，以及 NS3 可用来研究其性能的工具。我们的努力是让初学者能够轻松使用 NS3 构建 DCN 的流行设计并研究其性能。\n1.2 研究动机 数据中心的网络设计通常需要大量的成本\n单个FPGA网卡的成本超过$599.0，在验证DCN可行性时成本是不可估算的\n1.3 主要贡献 使用NS3仿真DCN：Fat-Tree、BCube、DCell、PortLand、4-4、1-4等 2. 实现方法 在他们提出的工作中实现DCN的不同设计\n3.1 Fat-Tree 一个 k-ary 的胖树结构由k个 Pod 组成，每个 Pod 由 k/2 个 k 端口的交换机组成两层网络，k 端口的交换机中的k/2个端口连接下一层级的主机，剩余的 k/2 个端口连接上一层级，最终聚合到核心层。\n以 10.0.0.0/8 地址段为例，可以为胖树网络进行IP编址\n3.2 BCube BCube_0 是一个 BCube 网络拓扑的基础，可以将 n 个服务器连接到 1 个 n 端口的交换机上\nBCube_1 由 BCube_0 演化而来，由 n 个 BCube_0 和 n 个 n 端口的路由器组成\nBCubel_k 由 n 个 BCube_{k-1} 和 n^k 个 n 端口的交换机组成\nData transfer in BCube uses BCube Source Routing (BSR) 3.3 PortLand PortLand 在设计时假定数据中心拓扑结构类似于多根树胖树。利用已知的基线拓扑和胖树生长模型，PortLand 使用轻量级协议（如LDP）确定拓扑中交换机的位置。\n使用48-bit的PMAC作为地址\n经过PMAC的地址发现，在交换机中实现PMAC到AMAC的重写实现数据流的转发\n","permalink":"https://www.zzudongxiang.com/posts/ns3-data-center-networks/","summary":"\u003cdiv\u003e\n\u003ch2 id=\"1-文章简介\"\u003e1. 文章简介\u003c/h2\u003e\n\u003ch3 id=\"11-摘要\"\u003e1.1 摘要\u003c/h3\u003e\n\u003cp\u003e部署在数据中心网络（DCN）上的应用日益复杂和先进，对 DCN 的新功能和更高性能提出了更高要求。这就产生了许多设计，以应对成本、性能、可靠性、可扩展性、安全性和能源等各种挑战。设计人员经常面临的一个主要挑战是如何实现他们提出的设计或实现现有设计进行比较。虽然原型设计是更好的选择，但它有一定的局限性，而且非常复杂和昂贵。因此，仿真被认为是原型设计的替代方案。\u003c/p\u003e\n\u003cp\u003e本文介绍了使用网络Network Simulator 3（NS3）实现 DCN 的各种架构并研究其性能的案例研究。我们提供的信息包括最流行的 DCN 设计的实现，以及 NS3 可用来研究其性能的工具。我们的努力是让初学者能够轻松使用 NS3 构建 DCN 的流行设计并研究其性能。\u003c/p\u003e\n\u003ch3 id=\"12-研究动机\"\u003e1.2 研究动机\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e数据中心的网络设计通常需要大量的成本\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e单个FPGA网卡的成本超过$599.0，在验证DCN可行性时成本是不可估算的\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"13-主要贡献\"\u003e1.3 主要贡献\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e使用NS3仿真DCN：Fat-Tree、BCube、DCell、PortLand、4-4、1-4等\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-实现方法\"\u003e2. 实现方法\u003c/h2\u003e\n\u003cp\u003e在他们提出的工作中实现DCN的不同设计\u003c/p\u003e\n\u003cimg src=\"images/image-kamt.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003ch3 id=\"31-fat-tree\"\u003e3.1 Fat-Tree\u003c/h3\u003e\n\u003cp\u003e一个 k-ary 的胖树结构由k个 \u003cem\u003ePod\u003c/em\u003e 组成，每个 \u003cem\u003ePod\u003c/em\u003e 由 k/2 个 k 端口的交换机组成两层网络，k 端口的交换机中的k/2个端口连接下一层级的主机，剩余的 k/2 个端口连接上一层级，最终聚合到核心层。\u003c/p\u003e\n\u003cimg src=\"images/image-wcph.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003cp\u003e以 \u003cem\u003e10.0.0.0/8\u003c/em\u003e 地址段为例，可以为胖树网络进行IP编址\u003c/p\u003e\n\u003ch3 id=\"32-bcube\"\u003e3.2 BCube\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eBCube_0 是一个 \u003cem\u003eBCube\u003c/em\u003e 网络拓扑的基础，可以将 n 个服务器连接到 1 个 n 端口的交换机上\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eBCube_1 由 BCube_0 演化而来，由 n 个 BCube_0 和 n 个 n 端口的路由器组成\u003c/p\u003e","title":"文献阅读《NS3 Simulator for a study of Data Center Networks》"},{"content":" 1. 文章简介 1.1 摘要 开源和社区支持的 gem5 仿真器是计算机体系结构研究领域最流行的工具之一。这种仿真基础架构允许研究人员在周期级别对现代计算机硬件进行建模，其保真度足以启动未经修改的基于Linux的操作系统，并为包括x86、Arm®和RISC-V在内的多种体系结构运行完整的应用程序。自gem5最初发布以来，gem5模拟器在过去九年中一直处于积极开发阶段。在此期间，有超过 250 位独特的贡献者对代码库进行了 7000 多次提交，通过添加新功能、修复错误和提高代码质量来改进模拟器。在本文中，我们将概述gem5的用法和功能，描述gem5模拟器的现状，并列举自gem5首次发布以来的主要变化。我们还讨论了gem5模拟器如何过渡到正式的管理模式，以便在未来20年的计算机体系结构研究中实现持续改进和社区支持。\n1.2 主要贡献 gem5 可通过基于 Python 的强大脚本界面进行动态配置。大多数其他模拟器都是通过平面文本文件（如 json）或在编译时进行静态配置的。另一方面，gem5 允许用户使用面向对象的 Python 脚本将较简单的系统组成更复杂的系统，从而更轻松地模拟复杂系统。\ngem5 可通过简洁的模型应用程序接口进行扩展。gem5模拟器有300多个参数化模型，添加新模型和参数简单明了，并有详细的文档说明。\ngem5 是一个完整的系统模拟器。其高保真模型可支持启动未修改的操作系统和运行未修改的应用程序，并提供周期级统计数据。\ngem5 是一个由社区驱动并经常更新的项目。gem5 社区蓬勃发展。自九年前首次发布以来，已有 250 多名独特的贡献者和 7000 多次提交。即使在过去六个月中，gem5 也有超过 850 次提交和 50 个独特的贡献者。\n2. 实现方法 gem5的简单使用方法\ngem5的组成部分\n","permalink":"https://www.zzudongxiang.com/posts/gem5-simulator/","summary":"\u003cdiv\u003e\n\u003ch2 id=\"1-文章简介\"\u003e1. 文章简介\u003c/h2\u003e\n\u003ch3 id=\"11-摘要\"\u003e1.1 摘要\u003c/h3\u003e\n\u003cp\u003e开源和社区支持的 gem5 仿真器是计算机体系结构研究领域最流行的工具之一。这种仿真基础架构允许研究人员在周期级别对现代计算机硬件进行建模，其保真度足以启动未经修改的基于Linux的操作系统，并为包括x86、Arm®和RISC-V在内的多种体系结构运行完整的应用程序。自gem5最初发布以来，gem5模拟器在过去九年中一直处于积极开发阶段。在此期间，有超过 250 位独特的贡献者对代码库进行了 7000 多次提交，通过添加新功能、修复错误和提高代码质量来改进模拟器。在本文中，我们将概述gem5的用法和功能，描述gem5模拟器的现状，并列举自gem5首次发布以来的主要变化。我们还讨论了gem5模拟器如何过渡到正式的管理模式，以便在未来20年的计算机体系结构研究中实现持续改进和社区支持。\u003c/p\u003e\n\u003ch3 id=\"12-主要贡献\"\u003e1.2 主要贡献\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003egem5 可通过基于 Python 的强大脚本界面进行动态配置。大多数其他模拟器都是通过平面文本文件（如 json）或在编译时进行静态配置的。另一方面，gem5 允许用户使用面向对象的 Python 脚本将较简单的系统组成更复杂的系统，从而更轻松地模拟复杂系统。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003egem5 可通过简洁的模型应用程序接口进行扩展。gem5模拟器有300多个参数化模型，添加新模型和参数简单明了，并有详细的文档说明。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003egem5 是一个完整的系统模拟器。其高保真模型可支持启动未修改的操作系统和运行未修改的应用程序，并提供周期级统计数据。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003egem5 是一个由社区驱动并经常更新的项目。gem5 社区蓬勃发展。自九年前首次发布以来，已有 250 多名独特的贡献者和 7000 多次提交。即使在过去六个月中，gem5 也有超过 850 次提交和 50 个独特的贡献者。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-实现方法\"\u003e2. 实现方法\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003egem5的简单使用方法\u003c/strong\u003e\u003c/p\u003e\n\u003cimg src=\"images/image-heep.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003cp\u003e\u003cstrong\u003egem5的组成部分\u003c/strong\u003e\u003c/p\u003e\n\u003cimg src=\"images/image-zxsl.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003c/div\u003e","title":"文献阅读《The GEM5 Simulator》"},{"content":" 在XYZ维度拓扑结构类似3D Torus架构\n在ABC维度按照如图所示的架构链接\n每个节点需要引出来10个链接，每XYZB轴各2条，AC轴为1条\nTofu架构先在ABC维度上进行拓扑，将12个Node互联形成一个Group\n然后再在XYZ维度上进行Torus拓扑，最终实现数万个Node互联\n每个Node使用一个（X,Y,Z,A,B,C）作为地址\n主动路径算法支持最多12条路径\n可以主动屏蔽故障路径\n多路径中继策略\n","permalink":"https://www.zzudongxiang.com/posts/tofu-torus/","summary":"\u003cdiv\u003e\n\u003cimg src=\"images/image-20240614185953351.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e在XYZ维度拓扑结构类似3D Torus架构\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e在ABC维度按照如图所示的架构链接\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e每个节点需要引出来10个链接，每XYZB轴各2条，AC轴为1条\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cimg src=\"images/image-20240614190912454.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eTofu架构先在ABC维度上进行拓扑，将12个Node互联形成一个Group\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e然后再在XYZ维度上进行Torus拓扑，最终实现数万个Node互联\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e每个Node使用一个（X,Y,Z,A,B,C）作为地址\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cimg src=\"images/image-20240614191437463.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e主动路径算法支持最多12条路径\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e可以主动屏蔽故障路径\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e多路径中继策略\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e","title":"文献阅读《Tofu: a 6D mesh/torus interconnect for exascale computers》"},{"content":" 1. 内容简介 1.1 摘要 为了应对机器学习（ML）模型的创新，生产工作负载发生了翻天覆地的变化。TPU v4 是谷歌第五个特定领域架构（DSA），也是第三台用于此类 ML 模型的超级计算机。光路交换机（OCS）可以动态地重新配置其互连拓扑结构，以提高规模、可用性、利用率、模块化、部署、安全性、功耗和性能；如果需要，用户可以选择扭曲的三维环形拓扑结构。与 Infiniband 相比，OCS 的成本更低、功耗更小、速度更快，OCS 和底层光学元件占系统成本的比例小于 5%，占系统功耗的比例小于 3%。每个 TPU v4 都包含 SparseCores 数据流处理器，可将依赖嵌入的模型加速 5-7 倍，但仅占用 5% 的芯片面积和功耗。自 2020 年部署以来，TPU v4 的性能是 TPU v3 的 2.1 倍，性能/瓦特数提高了 2.7 倍。TPU v4 超级计算机的芯片数量为 4096 个，是 TPU v3 的 4 倍，因此整体速度提高了近 10 倍，再加上 OCS 的灵活性和可用性，大型语言模型的平均训练速度可达到峰值 FLOPS/second 的 60%。对于类似大小的系统，它比 Graphcore IPU Bow 快 4.3-4.5 倍，比 Nvidia A100 快 1.2-1.7 倍，功耗低 1.3-1.9 倍。谷歌云能源优化仓库规模计算机内的 TPU v4 与典型内部数据中心的当代 DSA 相比，能耗降低约 2-6 倍，二氧化碳排放量降低约 20 倍。\n1.2 主要工作（与网络相关的） TPU v4采用了3D Torus网络结构，将TPU芯片按照三维立方体排列，提供高带宽、低延迟的通信链路\n为进一步优化通信性能，TPU v4引入了Twisted Torus结构。通过重新布线，Twisted Torus减少了最坏情况下的通信延迟，增加了网络的双向带宽\n通过采用Twisted Torus结构，TPU v4显著优化了全网通信性能，减少了通信延迟，提高了吞吐量\n2. 主要方法 2.1 Twisted Torus \u0026amp; 3D Torus TPUv4使用OCS可以动态的调整网络结构，例如将ML的任务切分成512个子任务，可以使用Cigar形状的4x4x32，也可以使用Cube的8x8x8，不同的拓扑有不同的性能\n针对完美Cube的Torus网络的训练性能较好（例如使用512个TPU组成8x8x8的拓扑），但是对于非完美的Cube的拓扑结构可能较差\nTwisted Torus建立了 4^3 个立方体之间的一些链接，以减少最坏情况下的延迟\n每个 TPU 都标有其在切片中的坐标\n电气连接（红色虚线）保持固定，通过利用 OCS 的灵活性，光连接（蓝色实线）可以从矩形环重新配置为扭曲环，而无需对机器进行任何物理重新布线\n测量为稳定状态（总传输大小较大），单个 DMA 为 4 KiB\n每列显示了与理想峰值的理论偏差，以叠加条形图的形式出现，并在测量结果上方标注\n2.2 Distribution of Topologies 生产中使用的切片拓扑结构示例：\n远小于4^3的Task可以使用2D Mesh，占比29%\n剩下的71%中，只有使用nxnx2n或者nx2nx2n的可以使用Twisted Torus，占比33%（48% of 71%）\n实际使用Twisted的只有28%（86% of 33%）\n换句话说，在多于4^3个Tasks中，有超过40%的可以使用Twisted Torus\n","permalink":"https://www.zzudongxiang.com/posts/tpu-v4/","summary":"\u003cdiv\u003e\n\u003ch2 id=\"1-内容简介\"\u003e1. 内容简介\u003c/h2\u003e\n\u003ch3 id=\"11-摘要\"\u003e1.1 摘要\u003c/h3\u003e\n\u003cp\u003e为了应对机器学习（ML）模型的创新，生产工作负载发生了翻天覆地的变化。TPU v4 是谷歌第五个特定领域架构（DSA），也是第三台用于此类 ML 模型的超级计算机。\u003cstrong\u003e光路交换机（OCS）可以动态地重新配置其互连拓扑结构，以提高规模、可用性、利用率、模块化、部署、安全性、功耗和性能；如果需要，用户可以选择扭曲的三维环形拓扑结构。与 Infiniband 相比，OCS 的成本更低、功耗更小、速度更快\u003c/strong\u003e，OCS 和底层光学元件占系统成本的比例小于 5%，占系统功耗的比例小于 3%。每个 TPU v4 都包含 SparseCores 数据流处理器，可将依赖嵌入的模型加速 5-7 倍，但仅占用 5% 的芯片面积和功耗。自 2020 年部署以来，TPU v4 的性能是 TPU v3 的 2.1 倍，性能/瓦特数提高了 2.7 倍。TPU v4 超级计算机的芯片数量为 4096 个，是 TPU v3 的 4 倍，因此整体速度提高了近 10 倍，再加上 OCS 的灵活性和可用性，大型语言模型的平均训练速度可达到峰值 FLOPS/second 的 60%。对于类似大小的系统，它比 Graphcore IPU Bow 快 4.3-4.5 倍，比 Nvidia A100 快 1.2-1.7 倍，功耗低 1.3-1.9 倍。谷歌云能源优化仓库规模计算机内的 TPU v4 与典型内部数据中心的当代 DSA 相比，能耗降低约 2-6 倍，二氧化碳排放量降低约 20 倍。\u003c/p\u003e","title":"文献阅读《TPU v4: An optically reconfigurable supercomputer for machine learning with hardware support ...》"},{"content":" 1. 文章简介 1.1 摘要 在复杂的网络化异构系统时代，仅对设计中系统的部分、组件或属性进行独立仿真是不可行、不准确或不高效的。交互作用太多、太复杂，无法产生有意义的结果，而且以孤立的方式考虑系统的每个部分时，优化机会受到严重限制。所介绍的 COSSIM 仿真框架是首个已知的开源高性能仿真器，可全面处理包括处理器、外设和网络在内的系统；这种方法对 CPS/IoT 和高并行异构系统设计人员和应用开发人员都非常有吸引力。我们的高度集成方法通过精确的功率估算和安全子工具得到了进一步增强，这些工具可以挖掘所有系统组件，并对整个网络系统进行安全性和稳健性分析。此外，我们还开发了一个图形用户界面，以提供简便的仿真设置、执行和结果可视化。COSSIM 已在云计算和 CPS 系统的实际应用中进行了评估，显示出很高的准确性和性能，几乎与专用于模拟器的 CPU 数量成线性关系。\n1.2 研究动机 针对CPS/IoT或依赖高度并行的异构系统的仿真场景，没有现有的、可靠的、高精度、高性能的工具\n现有工具主要分为两类：\n一种面向系统功能设计，针对物理器件、处理器、电子组件、用户行为、事件、消息等（Ptolemy、Matlab Simulink、Modelica-based Simulation Environments）\n另外一种可以处理周期精度、功耗等，主要在WSN中广泛应用（TOSSIM、COOJA）\n在云服务器仿真中常用的是：CloudSim及其衍生物\n1.3 主要贡献 构建了一套COSSIM的仿真工具，具有高精度、高可信、高效的特点\n仿真工具可以对系统性能、功耗、网络、安全等多方面进行评估\n仿真工具主要面向两种系统：一种是Encompasses Systems（WSN、CPS、IoT等），另外一种是Cloud and Parallel/Distributed Systems\n2. 实现方法 COSSIM主要针对的软件栈、动态网络、能耗仿真等几个方面\n2.1 COSSIM组成 2.1.1 处理器仿真 主要使用 GEM5 对节点（处理器）进行仿真，它可以满足对周期精度、指令集、可配置等多个条件。但是由于GEM5不支持对能耗的仿真，因此使用 McPAT 对能耗进行补充\n2.1.2 网络仿真 GEM5虽然可以支持到网络网卡（NIC）层级的仿真，但是不支持网络建模。使用 OMNET++ 处理从网卡层级及以上的仿真。\n2.1.3 组件集成 需要在处理器仿真与网络仿真之间细心的设计通信接口和同步方案。使用 IEEE HLA 对网络数据、消息、同步等进行网络控制\n2.2 COSSIM实现 用户输入系统配置、运行的应用、系统镜像、网络拓扑等参数，通过仿真可以得到处理器/网络状态、应用是模拟输出、功耗等信息\nGEM5和McPAT模块用于仿真节点，在运行的时候是多个实例进行并行的\nOMNET++用于多节点之间的网络模拟\n在节点（GEM5）和网络（OMNET++）之间通过HLA进行时钟同步\n使用嵌入的COSSIMlib控制节点间的同步策略和全局同步策略\n同一个网络上可以有多个不同算力，不同配置的GEM5实例，且节点间需要同时交换信息，因此同步是必要的\n3. 实验结果 COSSIM在移动视觉搜索应用和建筑管理系统应用上进行仿真和验证\n3.1 移动视觉搜索 移动视觉搜索（Mobile Visual Search，MVS）是一个计算机视觉应用，主要分为图像分析和搜索两个阶段\n实验条件：\nMobile Odroid XU3 (equipped with a quad Cortex-A15 and a quad Cortex-A7)\nMobile STMicroelectronics B2260 (a dualcore Cortex-A9)\nServer Intel Core i5-5200 quad core processor\nNetwork The server and the mobile nodes are connected through a wireless link\n精度结果\n速度结果\n3.2 性能扩展 当物理 CPU 内核数与模拟系统中的节点数相匹配时，性能下降幅度很小\n一旦节点数超过可用 CPU 内核数，性能就会急剧下降\n此外，我们还可以观察到分布式模拟场景网络的影响是有限的\n","permalink":"https://www.zzudongxiang.com/posts/cossim/","summary":"\u003cdiv\u003e\n\u003ch2 id=\"1-文章简介\"\u003e1. 文章简介\u003c/h2\u003e\n\u003ch3 id=\"11-摘要\"\u003e1.1 摘要\u003c/h3\u003e\n\u003cp\u003e在复杂的网络化异构系统时代，仅对设计中系统的部分、组件或属性进行独立仿真是不可行、不准确或不高效的。交互作用太多、太复杂，无法产生有意义的结果，而且以孤立的方式考虑系统的每个部分时，优化机会受到严重限制。所介绍的 COSSIM 仿真框架是首个已知的开源高性能仿真器，可全面处理包括处理器、外设和网络在内的系统；这种方法对 CPS/IoT 和高并行异构系统设计人员和应用开发人员都非常有吸引力。我们的高度集成方法通过精确的功率估算和安全子工具得到了进一步增强，这些工具可以挖掘所有系统组件，并对整个网络系统进行安全性和稳健性分析。此外，我们还开发了一个图形用户界面，以提供简便的仿真设置、执行和结果可视化。COSSIM 已在云计算和 CPS 系统的实际应用中进行了评估，显示出很高的准确性和性能，几乎与专用于模拟器的 CPU 数量成线性关系。\u003c/p\u003e\n\u003ch3 id=\"12-研究动机\"\u003e1.2 研究动机\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e针对CPS/IoT或依赖高度并行的异构系统的仿真场景，没有现有的、可靠的、高精度、高性能的工具\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e现有工具主要分为两类：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e一种面向系统功能设计，针对物理器件、处理器、电子组件、用户行为、事件、消息等（Ptolemy、Matlab Simulink、Modelica-based Simulation Environments）\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e另外一种可以处理周期精度、功耗等，主要在WSN中广泛应用（TOSSIM、COOJA）\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e在云服务器仿真中常用的是：CloudSim及其衍生物\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"13-主要贡献\"\u003e1.3 主要贡献\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e构建了一套COSSIM的仿真工具，具有高精度、高可信、高效的特点\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e仿真工具可以对系统性能、功耗、网络、安全等多方面进行评估\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e仿真工具主要面向两种系统：一种是Encompasses Systems（WSN、CPS、IoT等），另外一种是Cloud and Parallel/Distributed Systems\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-实现方法\"\u003e2. 实现方法\u003c/h2\u003e\n\u003cp\u003eCOSSIM主要针对的软件栈、动态网络、能耗仿真等几个方面\u003c/p\u003e\n\u003ch3 id=\"21-cossim组成\"\u003e2.1 COSSIM组成\u003c/h3\u003e\n\u003ch4 id=\"211-处理器仿真\"\u003e2.1.1 处理器仿真\u003c/h4\u003e\n\u003cp\u003e主要使用 \u003cstrong\u003eGEM5\u003c/strong\u003e 对节点（处理器）进行仿真，它可以满足对周期精度、指令集、可配置等多个条件。但是由于GEM5不支持对能耗的仿真，因此使用 \u003cstrong\u003eMcPAT\u003c/strong\u003e 对能耗进行补充\u003c/p\u003e\n\u003ch4 id=\"212-网络仿真\"\u003e2.1.2 网络仿真\u003c/h4\u003e\n\u003cp\u003eGEM5虽然可以支持到网络网卡（NIC）层级的仿真，但是不支持网络建模。使用 \u003cstrong\u003eOMNET++\u003c/strong\u003e 处理从网卡层级及以上的仿真。\u003c/p\u003e\n\u003ch4 id=\"213-组件集成\"\u003e2.1.3 组件集成\u003c/h4\u003e\n\u003cp\u003e需要在处理器仿真与网络仿真之间细心的设计通信接口和同步方案。使用 \u003cstrong\u003eIEEE HLA\u003c/strong\u003e 对网络数据、消息、同步等进行网络控制\u003c/p\u003e\n\u003ch3 id=\"22-cossim实现\"\u003e2.2 COSSIM实现\u003c/h3\u003e\n\u003cimg src=\"images/image-uxry.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e用户输入\u003ccode\u003e系统配置\u003c/code\u003e、\u003ccode\u003e运行的应用\u003c/code\u003e、\u003ccode\u003e系统镜像\u003c/code\u003e、\u003ccode\u003e网络拓扑\u003c/code\u003e等参数，通过仿真可以得到\u003ccode\u003e处理器/网络状态\u003c/code\u003e、\u003ccode\u003e应用是模拟输出\u003c/code\u003e、\u003ccode\u003e功耗\u003c/code\u003e等信息\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eGEM5和McPAT模块用于仿真节点，在运行的时候是多个实例进行并行的\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eOMNET++用于多节点之间的网络模拟\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e在节点（GEM5）和网络（OMNET++）之间通过HLA进行时钟同步\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e使用嵌入的COSSIMlib控制节点间的同步策略和全局同步策略\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e同一个网络上可以有多个不同算力，不同配置的GEM5实例，且节点间需要同时交换信息，因此同步是必要的\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"3-实验结果\"\u003e3. 实验结果\u003c/h2\u003e\n\u003cp\u003eCOSSIM在\u003ccode\u003e移动视觉搜索应用\u003c/code\u003e和\u003ccode\u003e建筑管理系统应用\u003c/code\u003e上进行仿真和验证\u003c/p\u003e\n\u003ch3 id=\"31-移动视觉搜索\"\u003e3.1 移动视觉搜索\u003c/h3\u003e\n\u003cp\u003e移动视觉搜索（Mobile Visual Search，MVS）是一个计算机视觉应用，主要分为图像分析和搜索两个阶段\u003c/p\u003e","title":"文献阅读《COSSIM: An open-source integrated solution to address the simulator gap for systems of systems》"},{"content":" WANG W, KHAZRAEE M, ZHONG Z, et al. TopoOpt: Co-optimizing Network Topology and Parallelization Strategy for Distributed Training Jobs \\[Z\\]. NSDI. 2023 https://www.usenix.org/conference/nsdi23/presentation/wang-weiyang\n论文简介 1. 摘要 本文提出一种新的适用于DNN的直连结构网络$T_{OPO}O_{PT}$，它可以在计算、通信和网络拓扑三个维度上优化分布式训练的过程。我们演示了 AllReduce 流量的可变性，并利用此属性为 DNN 训练作业构建高效的网络拓扑。然后，$T_{OPO}O_{PT}$使用交替优化技术和名为TotientPerms的群论启发算法来找到最佳网络拓扑和路由计划以及并行化策略。我们构建了一个功能齐全的 12 节点直连原型，具有 100 Gbps 的远程直接内存访问 (RDMA) 转发。对真实分布式训练模型的大规模模拟表明，与类似成本的 Fat-tree 互连相比，TOPOOPT 将 DNN 训练时间减少了高达 3.4 倍。\n2. 主要贡献 综合考虑了计算、通信和网络拓扑三个维度的优化策略\n分析了MP与AllReduce的流量特征\n利用AllReduce的流量可变性优化AllReduce路径\n利用交替优化技术和TotientPerms算法来找到最佳网络拓扑\n在12个节点的情况下，比传统的胖树网络降低了DNN的3.4倍训练时间\n实现方法 1. $T_{OPO}O_{PT}$架构 假定有n个Server，每个Server有d个接口，每个接口连接一个Optical Seicth，共计需要d个Optical Switch。Optical Switch可以通过配置可以在内部视作直接连接任意两个端口，从而实现任意两个Server之间的直接连接。\n论文中提到Server与Optical Switch之间的连接是使用RDMA网卡，并对其进行了修改：原生RDMA网卡会抛弃非本机的数据，修改后支持数据转发和数据中继。\nTOPOOPT的网络连接方式\n论文中称Server的端口数量d为Server的Degree，它决定着每个Server与其他Server的连接数量，也是 $T_{OPO}O_{PT}$ 算法的一个计算参数。\n2. 交替优化策略 问题：\n从计算、通信、网络拓扑三个维度对并行计算进行优化会产生一个非常大的搜索空间，导致该优化问题可能无法求得最优解。\n通过先优化并行策略再优化网络拓扑的方法可能寻找到局部最优解，但是很难搜索到全局最优解。\n解决：\nTOPOOPT搜索策略\n将网络划分为两个平面：计算×通信 (Comp.×Comm.) 和 通信×拓扑 (Comm. × Topo.)，通过交替优化策略，在其中一个平面搜索时保持另外一个平面的结果不变。\n在计算×通信 (Comp.×Comm.)平面使用FlexFlow的MCMC（Markov Chain Monte Carlo）搜索算法在给定的拓扑结构下寻找最优的并行策略。\n在通信×拓扑 (Comm. × Topo.)平面使用$T_{OPOLOGY}F_{INDER}$算法寻找在给定的并行策略下最优的拓扑结构和布线策略。\n然后循环迭代多次，直到结果收敛到指定的结果或满足一定的迭代次数。\n3. $T_{OPOLOGY}F_{INDER}$搜索算法 算法的输入参数：\nn：Server的数量\nd：每个Server的Degree\n$T_{AllReduce}$：基于指定并行策略和设备的AllReduce传输列表\n$T_{MP}$：基于指定并行策略和设备的MP传输列表\n算法的输出结果：\nG：最优的网络拓扑\nR：最优拓扑下的布线规则\n算法实现步骤：\n4. 不同的传输流量 通过改变网络拓扑结构，使之前的第i个节点传输给第$(i+1)\\%n$个节点的方式变成+3或者+7，通过热力图分析发现，通过网络传输的数据主要可以分为两种：\n图中颜色较深的，倾斜的线段为AllReduce传输流量，它会随着网络拓扑的改变发生改变\n途中颜色较浅的，水平或垂直分布的为模型并行传输流量，它与网络拓扑的跳数无关\nDLRM网络一次迭代的流量热力图\n5. 利用AllReduce路径的可变性 在AllReduce的过程中，从A点到B点可以根据网络拓扑的结构不同有多种路径，当存在16个节点，且每个节点的Degree为3时，可以将网络拓扑的结构优化为下图方式，此时一次训练迭代的流量热力图也会发生改变，总传输流量不变的情况下，点对点的通信量下降，可以时点对点的传输效率更高，进而提高训练速度。\nTOPOOPT优化后的拓扑结构和流量热力图\n实验结果 原文对进行了大规模的仿真和小规模的实际测试，对带宽、模型、Server数量、Server的Degree、Batch Size等多个参数进行了详细的测试与仿真，请参考原文内容。\n","permalink":"https://www.zzudongxiang.com/posts/topoopt/","summary":"\u003cdiv\u003e\n\u003cblockquote\u003e\n\u003cp\u003eWANG W, KHAZRAEE M, ZHONG Z, et al. TopoOpt: Co-optimizing Network Topology and Parallelization Strategy for Distributed Training Jobs \u003c/p\u003e\n\\[Z\\]\u003cp\u003e. NSDI. 2023 \u003ca href=\"https://www.usenix.org/conference/nsdi23/presentation/wang-weiyang\"\u003ehttps://www.usenix.org/conference/nsdi23/presentation/wang-weiyang\u003c/a\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"论文简介\"\u003e论文简介\u003c/h2\u003e\n\u003ch3 id=\"1-摘要\"\u003e1. 摘要\u003c/h3\u003e\n\u003cp\u003e本文提出一种新的适用于DNN的直连结构网络$T_{OPO}O_{PT}$，它可以在计算、通信和网络拓扑三个维度上优化分布式训练的过程。我们演示了 AllReduce 流量的可变性，并利用此属性为 DNN 训练作业构建高效的网络拓扑。然后，$T_{OPO}O_{PT}$使用交替优化技术和名为TotientPerms的群论启发算法来找到最佳网络拓扑和路由计划以及并行化策略。我们构建了一个功能齐全的 12 节点直连原型，具有 100 Gbps 的远程直接内存访问 (RDMA) 转发。对真实分布式训练模型的大规模模拟表明，与类似成本的 Fat-tree 互连相比，TOPOOPT 将 DNN 训练时间减少了高达 3.4 倍。\u003c/p\u003e\n\u003ch3 id=\"2-主要贡献\"\u003e2. 主要贡献\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e综合考虑了计算、通信和网络拓扑三个维度的优化策略\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e分析了MP与AllReduce的流量特征\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e利用AllReduce的流量可变性优化AllReduce路径\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e利用交替优化技术和TotientPerms算法来找到最佳网络拓扑\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e在12个节点的情况下，比传统的胖树网络降低了DNN的3.4倍训练时间\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"实现方法\"\u003e实现方法\u003c/h2\u003e\n\u003ch3 id=\"1-架构\"\u003e1. $T_{OPO}O_{PT}$架构\u003c/h3\u003e\n\u003cp\u003e假定有n个Server，每个Server有d个接口，每个接口连接一个Optical Seicth，共计需要d个Optical Switch。Optical Switch可以通过配置可以在内部视作直接连接任意两个端口，从而实现任意两个Server之间的直接连接。\u003c/p\u003e\n\u003cp\u003e论文中提到Server与Optical Switch之间的连接是使用RDMA网卡，并对其进行了修改：原生RDMA网卡会抛弃非本机的数据，修改后支持数据转发和数据中继。\u003c/p\u003e\n\u003cimg src=\"images/image-20240516221333441.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" /\u003e\n\u003cp\u003eTOPOOPT的网络连接方式\u003c/p\u003e\n\u003cp\u003e论文中称Server的端口数量d为Server的Degree，它决定着每个Server与其他Server的连接数量，也是 $T_{OPO}O_{PT}$ 算法的一个计算参数。\u003c/p\u003e\n\u003ch3 id=\"2-交替优化策略\"\u003e2. 交替优化策略\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003e问题\u003c/strong\u003e：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e从计算、通信、网络拓扑三个维度对并行计算进行优化会产生一个非常大的搜索空间，导致该优化问题可能无法求得最优解。\u003c/p\u003e","title":"文献阅读《TOPOOPT: Co-optimizing Network Topology and Parallelization Strategy...》"},{"content":" I. 前置内容 在了解集合通信（Collective Communication）之前要先了解点P2P对点通信（Point-to-Point）。P2P通信通常为两个不同进程间的通信，是1对1的； 在MPI规范中，既有同步阻塞的P2P接口：MPI_send和MPI_Recv接口，也定义了非阻塞的P2P接口如：MPI_Isend、MPI_Irecve。\n集合通信和P2P通信是相对应的，集合通信则是1对多或是多对多的。在分布式系统中，各个节点间往往存在大量的集合通信需求，而我们可以用消息传递接口（Message Passing Interface，MPI）来定义一些比较底层的消息通信行为譬如Reduce、Allreduce、Scatter、Gather、Allgather等。\n1.1 系统架构 集合通信算法的优化往往与其对应的网络拓扑和系统架构有直接关系，通常情况下，一个节点内的GPU-GPU或GPU-CPU之间的结构成为系统架构，节点之间的网络连接称为网络拓扑，一种确定的系统架构会有确定的网络拓扑架构。\n在HPC领域有很多经典的系统架构和网络拓扑，例如：Summit system或者Lassen system等。本文主要由于发表于2021年，很多系统架构和指标数据与当先最新数据差异较大，但是为了方便后续的理解，本文后续还是以Summit system和Lassen system为例进行分析。\n简化的Summit System和Lassen System（论文中的结构）\n每个节点包含6个GPU和2个CPU，每3个GPU和1个CPU组成一个Group，使用NVLink进行连接，CPU与CPU之间使用X-Bus进行连接，同时与IB网卡使用PCIe进行连接，节点间使用IB协议进行组网。NVLink、NVSwitch、IB等硬件设备的概念将会在下一节中介绍。\n1.2 相关组件 NVLink and NVSwitch\nNVLink和NVSwitch是一种可支持服务器内和服务器间实现高级多 GPU 通信的基础模组。第四代NVLink技术可为多 GPU 系统配置提供高于以往 1.5 倍的带宽，以及增强的可扩展性。第三代NVSwitch基于 NVLink 的高级通信能力构建，可为计算密集型工作负载提供更高带宽和更低延迟。\nMellanox InfiniBand\nInfiniBand（直译为“无限带宽”技术，缩写为IB）是一个用于高性能计算的计算机网络通信标准，它具有极高的吞吐量和极低的延迟，用于计算机与计算机之间的数据互连。InfiniBand也用作服务器与存储系统之间的直接或交换互连，以及存储系统之间的互连。常用的IB交换机/网卡带宽普遍为为400GB/s。\nRemote Direct Memory Access (RDMA)\nRDMA是一种概念，在两个或者多个计算机进行通讯的时候使用DMA， 从一个主机的内存直接访问另一个主机的内存。\n1.3 (Non-)Personalized All-to-All 1.3.1 Non-Personalized All-to-All Non-Personalized All-to-All（通常称为 MPI_Allgather）是一种 MPI 集体通信模式，是 MPI_Gather 和 MPI_Bcast 的结合。所有进程按等级顺序从其他进程收集数据。操作结束时，每个进程都将与所有其他进程交换数据。\n1.3.2 Personalized All-to-All Personalized All-to-All称为 MPI_Alltoall，与 MPI_Allgather 类似，所有进程都相互共享数据。然而，每个进程都会向其他进程发送不同的数据，从而形成一种个性化的集体通信模式（即，每个进程都会向每个其他进程发送不同的数据块）\n1.4 相关算法 1.4.1 Ring 每个进程i发送数据给(i+1) \\ N并从(i-1) \\ N接收数据，但是这种方法会带来过高的延迟。\n1.5.2 Recursive Doubling 每个进程i在第k (0\u0026lt;=2k\u0026lt;N)步发送数据给(i \\ XOR \\ 2^k)并从(i \\ XOR \\ 2^k)接收数据。这种方法能够有效降低延迟，但是缺点也显而易见，就是当进程数N不是2的幂的时候很不友好，需要特殊处理。\nRecursive Doubling算法\n1.5.3 Bruck Bruck算法可以看做是RD算法的一个改进，每个进程i第k (0 ≤ k \u0026lt; \\log_2 N)步发送数据给(i-2k) \\ N并从(i-2k) \\ N接收数据。\nBruck算法是优化后的环形算法，进一步降低通信的次数。它利用了倍增的思想：每次接收到数据后，本地数据量翻倍，然后把所有本地数据发送给没有这些数据的下一个节点。\n具体来说，对于节点i，在第j次通信的时候（j从1开始），把自身的所有数据发送给i−2j−1个节点。这样的话，仅需要发送\\log m次。算法流程如下图所示：\nBruck算法\n1.5.4 Pairwise-Exchange 每个进程i在第k (0\u0026lt;=2k\u0026lt;N)步发送数据给(i \\ XOR \\ {2^k}) \\ N并从(i \\ XOR \\ {2^k}) \\ N接收数据，其中XOR表示逻辑异或的位运算。同样这种算法对于进程数N不是2的幂的时候很麻烦。\nPairwise-Exchange算法\n1.5.5 Scatter-Destination TODO\nA. K. Singh, S. Potluri, H. Wang, K. Kandalla, S. Sur, and D. K. Panda, “Mpi alltoall personalized exchange on gpgpu clusters: Design alternatives and benefit,” in 2011 IEEE International Conference on Cluster Computing, Sep. 2011, pp. 420–427.\n1.5.6 Direct 直接根据目的直接send和recv不进行任何调度的方法，这里就是指 p 个进程，每个进程都调用 p-1 个MPI_Irecv和MPI_Isend，然后MPI_Waitall完事。\n1.5.7 Inplace TODO\n1.6 评价标准 OSU 微基准测试（OSU micro-benchmarks）具有一系列 MPI 基准测试，可衡量各种 MPI 操作的性能：\n点对点 MPI 基准：延迟、多线程延迟、多对延迟、多带宽/消息速率测试带宽、双向带宽\n集体 MPI 基准：各种 MPI 集体操作的集体延迟测试，例如 MPI_Allgather、MPI_Alltoall、MPI_Allreduce、MPI_Barrier、MPI_Bcast、MPI_Gather、MPI_Reduce、MPI_Reduce_Scatter、MPI_Scatter 和向量集体。\n单侧 MPI 基准：一侧放置延迟（主动/被动）、一侧放置带宽（主动/被动）、一侧放置双向带宽、一侧获取延迟（主动/被动）、 MVAPICH2（MPI-2 和 MPI-3）的单侧获取带宽（主动/被动）、单侧累积延迟（主动/被动）、比较和交换延迟（被动）以及获取和操作（被动）。\nII. 论文简介 2.1 摘要 近年来，GPU 增强型集群在高性能计算 (HPC) 领域变得越来越普遍，从而引发了对更高效的多 GPU 通信的需求。这使得探索通过 MPI 等通信中间件实现的性能增强变得越来越重要，以便充分利用这些系统上可用的 GPU。在本文中，我们提出了大规模密集 GPU 系统上分层 All-to-all 集体通信的局部感知和自适应方案。所提出的算法利用 GPU 之间的 NVLink 互连提供的高带宽来重叠通信延迟。我们专注于个性化和非个性化的全民集体沟通。这些是现代科学计算应用程序的组件，利用矩阵转置和三维快速傅立叶变换 (FFT)，并且与具有模型和混合并行性的深度学习工作负载变得更加相关。对执行三维 FFT 的应用程序内核进行的性能评估表明，所提出的个性化 all-to-all 方案可以将 Lassen 系统上 256 个 GPU 上的执行时间缩短 15-25%。我们展示了在多达 128 个 GPU 上进行深度学习训练时使用的分布式 K-FAC 的训练时间缩短了大约 8%。我们还证明，与 Summit 和 Lassen 系统上最先进的 MPI 库相比，非个性化和个性化全基准测试的性能分别提高了约 22% 和 30%1。\n2.2 主要贡献 在密集 GPU 系统上设计了一种分层、自适应和高利用率的个性化和非个性化全能通信算法。\n提出一种新的 All-to-all 算法，分解成对通信模式，并利用 GPU 之间可用的互连（例如 NVLink）来最大限度地减少链路空闲时间。\n提出一种先进的分层算法，实现节点间和节点内通信之间的高度重叠，以提高 All-to-all 和 Allgather 通信的性能。\n对最先进的 MPI 库中现有的 All-to-all 和 Allgather 通信算法进行综合评估。\n使用OSU微基准、3D FFT 应用内核和 KFAC 分布式 DNN，对所提出的设计和各种 CUDA 感知通信库（MVAPICH2GDR、Spectrum-MPI、NCCL 和 OpenMPI）进行 All-to-all 和 Allgather 集体的性能评估优化。\n2.3 题目关键词 自适应：根据Message Size的不同选择最合适的算法\n分层：在节点内选择一个GPU作为Leader，只有Leader能在节点间传输数据\n大消息：在Large Message上优化效果较好\nIII. 实现步骤 All to All 与 All Gather 相比较，区别在于：All Gather 操作中，不同进程向某一进程收集到的数据是完全相同的，而在 All to All 中，不同的进程向某一进程收集到的数据是不同的。在每个进程的发送缓冲区中，为每个进程都单独准备了一块数据4。\n3.1 Non-Personalized All-to-All 3.1.1 实现思路 主要目的是利用节点内高速连接的网络提高密集GPU集群种All Gather集合通信算法的效率，通过与节点间通信的Overlap，隐藏节点间通信的时间，进而提高NVLink的利用率。\n本文所提出的算法针对基于树状的网络拓扑结构，基于RD方法改进而来的。利用两个通信器分别连接节点内与节点间的两层网络，在节点内与节点间同步传输数据实现节点内与节点间的Overlap通信。\n3.1.2 实现步骤 A. 2 Nodes Allgather on 2 Nodes (8 Processes)\n原论文配图勘误：\n根据文章内容描述，图中的蓝色虚线应该由Inter-Node改为Intra-Node\n节点内的Gather操作方向应该为GPU1 \u0026ndash;\u0026gt; GPU0，GPU2 \u0026ndash;\u0026gt; GPU0\nB. 8 Nodes Allgather on 8 Nodes (32 Processes)\n8节点与单节点操作过程类似，类似2节点的过程，具体过程如下\n3.1.3 小结 由于Non-Personalized All-to-All的任一进程向其他进程发送的数据量和接收的数据量是相同的，因此在无收敛的网络结构种可以利用节点内通信的时间与节点间的通信时间同步进行，以提高效率。但是当节点内通信与节点间通信的数据量不同时，可能导致该时间无法完美Cover，导致集合通信的效率下降。\n在Summit system或者Lassen system中由于节点内跨CPU通信带宽受X-Bus带宽的限制，因此在实践时可能会造成阻塞导致集合通信效率降低。\n3.2 Eager Personalized All-to-All 3.2.1 实现思路 本文提出的Eager Personalized All-to-All算法是基于优化后的Pairwise通信，主要目的是隐藏节点间通信的时间。\n3.2.2 实现步骤 Eager All-to-all on 2 Nodes (8 Processes)\n3.2.3 小结 这种方法的好处是可以隐藏前几步的潜在的Intra-Node通信耗时。\n假定Inter-Node的连接方式为NVLink，Intra-Node的连接方式为IB，在Intra-Node通信时，GPU0 \u0026lt;\u0026ndash;\u0026gt; GPU4传输数据的动作会与GPU1 \u0026lt;\u0026ndash;\u0026gt; GPU5争抢IB交换机带宽，导致算法效率下降。\n3.3 Hierarchical and Adaptive All-to-All 3.3.1 实现思路 传统的All-to-All算法大多按照Pairwise或Scatter实现，这种实现方式的性能严重受IB交换机的带宽限制。本文所提出的方法利用Leader进行Inter-Node和Intra-Node的分层解决该问题。同时对消息的大小具有一定的自适应性，算法会根据Message Size的不同自动选择最优的算法。\n3.3.2 实现步骤 每个Node选择一个Leader，Leader之间进行Exchange数据，同时拿到数据后直接进行Gather和Scatter操作。以下的每一个步骤都是同时完成的，以确保在通信的时候没有IDLE时刻。\nHierarchical All-to-all: Step 1 of Execution\n同节点内的GPU使用NVLink相互交换（P2P直接收发）初始化的数据块（紫色虚线）\nNODE0.GPU1把对应的数据块Gather到NODE0.GPU0 (Leader)的临时Buffer（Sender Buffer）中\nNODE0.GPU0 (Leader)发送自己Send Buffer中的数据到NODE1.GPU4 (Leader)中\nHierarchical All-to-all: Step 2 of Execution\n当NODE0.GPU0 (Leader)和NODE1.GPU4 (Leader)收到对应的数据时直接Scatter到其他的GPU上\n同时NODE0.GPU2的数据Gather到NODE0.GPU0 (Leader)上\nHierarchical All-to-all: Step 3 of Execution\n重复以上操作，直到一个节点内的全部数据完成 Hierarchical All-to-all: Inter-Node Communication Pattern Between Node Leaders\n利用Pairwise算法在Leader之间交换数据，同时Leader会把数据Scatter到节点内的其他GPU上 3.3.3 小结 在节点内的传输过程类似Eager Personalized All-to-All算法，但是通过引入Leader的分层机制解决了同一个节点内的GPU抢占X-BUS带宽的问题。\nIV. 实验结果 本文使用到的抓取性能数据的工具有mpiP、nvprof、INAM等，测试的指标主要是Benchmark、算法应用性能、其他的CUDA并行库。\n4.1 Benchmark-Level Performance 测试条件：Lassen system，64个Node（256个GPU）与Summit system，64个Node（384个GPU）\n4.1.1 Result for Lassen Lassen系统上All-to-All算法不同节点数量的比较\n在8KB的Message Size上有20-30%的改进\n在256GPU and 1MB的Meesage Size条件下有39%的性能提升\n4.1.2 Result for Summit Summit系统上All-to-All算法不同节点数量的比较\n在Summit系统上有相似的结果，256GPU and 2MB的Message Size有35%的性能提升 4.1.3 AllGather算法比较 Lassen 系统上 Allgather 算法的不同算法比较\n比现存的最好的方法性能提升9~18% 4.2 3D-FFT Application Kernel Personalized all-to-all Algorithms for 3D FFT application kernel\n测试条件为Lassen System的64, 128, and 256 GPUs\n有15~20%的性能提升\n","permalink":"https://www.zzudongxiang.com/posts/adaptive-hierarchical-alltoall/","summary":"\u003cdiv\u003e\n\u003ch2 id=\"i-前置内容\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003eI. 前置内容\u003c/span\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e在了解集合通信（Collective Communication）之前要先了解点P2P对点通信（Point-to-Point）。P2P通信通常为两个不同进程间的通信，是1对1的； 在MPI规范中，既有同步阻塞的P2P接口：MPI_send和MPI_Recv接口，也定义了非阻塞的P2P接口如：MPI_Isend、MPI_Irecve。\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e集合通信和P2P通信是相对应的，集合通信则是1对多或是多对多的。在分布式系统中，各个节点间往往存在大量的集合通信需求，而我们可以用消息传递接口（Message Passing Interface，MPI）来定义一些比较底层的消息通信行为譬如Reduce、Allreduce、Scatter、Gather、Allgather等。\u003c/span\u003e\u003c/p\u003e\n\u003ch3 id=\"11-系统架构\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1.1 系统架构\u003c/span\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e集合通信算法的优化往往与其对应的网络拓扑和系统架构有直接关系，通常情况下，一个节点内的GPU-GPU或GPU-CPU之间的结构成为系统架构，节点之间的网络连接称为网络拓扑，一种确定的系统架构会有确定的网络拓扑架构。\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e在HPC领域有很多经典的系统架构和网络拓扑，例如：\u003c/span\u003e\u003ccode\u003eSummit system\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e或者\u003c/span\u003e\u003ccode\u003eLassen system\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e等。本文主要由于发表于2021年，很多系统架构和指标数据与当先最新数据差异较大，但是为了方便后续的理解，本文后续还是以\u003c/span\u003e\u003ccode\u003eSummit system\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e和\u003c/span\u003e\u003ccode\u003eLassen system\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e为例进行分析。\u003c/span\u003e\u003c/p\u003e\n\u003cimg src=\"images/image-qlmv.png\" style=\"display: inline-block;width:100.0%;height:100.0%\" alt=\"image-qlmv.png\" /\u003e\n\u003cp\u003e简化的Summit System和Lassen System（论文中的结构）\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e每个节点包含6个GPU和2个CPU，每3个GPU和1个CPU组成一个Group，使用\u003c/span\u003e\u003ccode\u003eNVLink\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e进行连接，CPU与CPU之间使用\u003c/span\u003e\u003ccode\u003eX-Bus\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e进行连接，同时与\u003c/span\u003e\u003ccode\u003eIB\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e网卡使用\u003c/span\u003e\u003ccode\u003ePCIe\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e进行连接，节点间使用\u003c/span\u003e\u003ccode\u003eIB\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e协议进行组网。\u003c/span\u003e\u003ccode\u003eNVLink\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e、\u003c/span\u003e\u003ccode\u003eNVSwitch\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e、\u003c/span\u003e\u003ccode\u003eIB\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e等硬件设备的概念将会在下一节中介绍。\u003c/span\u003e\u003c/p\u003e\n\u003ch3 id=\"12-相关组件\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1.2 相关组件\u003c/span\u003e\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e\u003cspan fontsize=\"\" color=\"\"\u003eNVLink and NVSwitch\u003c/span\u003e\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eNVLink\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e和\u003c/span\u003e\u003ccode\u003eNVSwitch\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e是一种可支持服务器内和服务器间实现高级多 GPU 通信的基础模组。第四代\u003c/span\u003e\u003ccode\u003eNVLink\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e技术可为多 GPU 系统配置提供高于以往 1.5 倍的带宽，以及增强的可扩展性。第三代\u003c/span\u003e\u003ccode\u003eNVSwitch\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e基于 \u003c/span\u003e\u003ccode\u003eNVLink \u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e的高级通信能力构建，可为计算密集型工作负载提供更高带宽和更低延迟。\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e\u003cspan fontsize=\"\" color=\"\"\u003eMellanox InfiniBand\u003c/span\u003e\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eInfiniBand\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e（直译为“无限带宽”技术，缩写为\u003c/span\u003e\u003ccode\u003eIB\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e）是一个用于高性能计算的计算机网络通信标准，它具有极高的吞吐量和极低的延迟，用于计算机与计算机之间的数据互连。\u003c/span\u003e\u003ccode\u003eInfiniBand\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e也用作服务器与存储系统之间的直接或交换互连，以及存储系统之间的互连。常用的IB交换机/网卡带宽普遍为为400GB/s。\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e\u003cspan fontsize=\"\" color=\"\"\u003eRemote Direct Memory Access (RDMA)\u003c/span\u003e\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eRDMA是一种概念，在两个或者多个计算机进行通讯的时候使用DMA， 从一个主机的内存直接访问另一个主机的内存。\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"13-non-personalized-all-to-all\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1.3 (Non-)Personalized All-to-All\u003c/span\u003e\u003c/h3\u003e\n\u003ch4 id=\"131-non-personalized-all-to-all\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1.3.1 Non-Personalized All-to-All\u003c/span\u003e\u003c/h4\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eNon-Personalized All-to-All（通常称为 MPI_Allgather）是一种 MPI 集体通信模式，是 MPI_Gather 和 MPI_Bcast 的结合。所有进程按等级顺序从其他进程收集数据。操作结束时，每个进程都将与所有其他进程交换数据。\u003c/span\u003e\u003c/p\u003e\n\u003ch4 id=\"132-personalized-all-to-all\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1.3.2 Personalized All-to-All\u003c/span\u003e\u003c/h4\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003ePersonalized All-to-All称为 MPI_Alltoall，与 MPI_Allgather 类似，所有进程都相互共享数据。然而，每个进程都会向其他进程发送不同的数据，从而形成一种个性化的集体通信模式（即，每个进程都会向每个其他进程发送不同的数据块）\u003c/span\u003e\u003c/p\u003e\n\u003ch3 id=\"14-相关算法\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1.4 相关算法\u003c/span\u003e\u003c/h3\u003e\n\u003ch4 id=\"141-ring\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1.4.1 Ring\u003c/span\u003e\u003c/h4\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e每个进程i发送数据给(i+1) \\ N并从(i-1) \\ N接收数据，但是这种方法会带来过高的延迟。\u003c/span\u003e\u003c/p\u003e","title":"文献阅读《Adaptive and Hierarchical Large Message All-to-all Communication Algorithms...》"},{"content":" 参考来源: 分布式训练常用的集合通信及其通信原语, 分布式训练常用的网络结构及集合通信拓扑算法\n图片来源：volta-architecture-whitepaper\n1 Broadcast Broadcast属于1对多的通信原语，一个数据发送者，多个数据接收者，可以在集群内把一个节点自身的数据广播到其他节点上。如下图所示，圈圈表示集群中的训练加速卡节点，相同的颜色的小方块则代表相同的数据。当主节点 0 执行Broadcast时，数据即从主节点0被广播至其他节点。\nBroadcast是数据的1对多的同步，它将一张XPU卡上的数据同步到其他所有的XPU卡上，其应用场景有：\n数据并行的参数初始化，确保每张卡上的初始参数是一致的；\nallReduce里的 broadcast + reduce组合里的broadcast操作；\n分布式训练parameter server 参数服务器结构里的 master节点 broadcast 数据到worker节点，再从worker节点reduce数据回master节点里的broadcast操作；\n2 Scatter 同Broadcast一样，Scatter也是一个1对多的通信原语，也是一个数据发送者，多个数据接收者，可以在集群内把一个节点自身的数据发散到其他节点上。与Broadcast不同的是Broadcast把主节点0的数据发送给所有节点，而Scatter则是将数据的进行切片再分发给集群内所有的节点，如下图所示，不相同的颜色的小方块代表不相同的数据，主节点 0 将数据分为四份分发到了节点0-3。\nScatter是数据的1对多的分发，它将一张XPU卡上的数据进行分片再分发到其他所有的XPU卡上，他的反向操作对应Gather，其应用场景有：\nReduceScatter组合里的 Scatter操作；\n模型并行里初始化时将模型scatter到不同的XPU上；\n3 Gather Gather操作属于多对1的通信原语，具有多个数据发送者，一个数据接收者，可以在集群内把多个节点的数据收集到一个节点上，如下图所示，不相同的颜色的小方块代表不相同的数据。\nGather是数据的多对1的收集，它将多张XPU卡上的数据收集到1张XPU卡上，它的反向操作对应Scatter，其应用场景有：\nReduceScatter组合里的 Scatter操作； 4 Reduce Reduce属于多对1的通信原语，具有多个数据发送者，一个数据接收者，可以在集群内把多个节点的数据规约运算到一个主节点上，常用的规约操作符有：求累加和SUM、求累乘积PROD、求最大值MAX、求最小值MIN、逻辑与 LAND、按位与BAND、逻辑或LOR、按位或BOR、逻辑异或LXOR、按位异或BOXR、求最大值和最小大的位置MAXLOC、求最小值和最小值的位置MINLOC等，这些规约运算也需要加速卡支持对应的算子才能生效。\nReuduce操作从集群内每个节点上获取一个输入数据，通过规约运算操作后，得到精简数据，如下图的SUM求累加和：节点0数值 5、节点1数值6、节点2数值7、节点3数值8，经过SUM运算后 累积和为 26，即得到更为精简的数值，在reduce原语里回会去调用 reduce SUM算子来完成这个求和累加。\nReduce是数据的多对1的规约运算，它将所有张XPU卡上的数据规约（比如SUM求和）到1张XPU卡上，其应用场景有：\nAllReduce里的 broadcast + reduce组合里的reduce操作；\nReduceScatter组合里的 reduce操作；\n分布式训练parameter server 参数服务器结构里的 master节点 broadcast 数据到worker节点，再从worker节点reduce数据回master节点里的reduce操作；\n5 All Gather AllGather属于多对多的通信原语，具有多个数据发送者，多个数据接收者，可以在集群内把多个节点的数据收集到一个主节点上（Gather），再把这个收集到的数据分发到其他节点上（broadcast），即收集集群内所有的数据到所有的节点上。\nAllGather是数据的多对多的同步全收集，它将多张XPU卡上的数据收集到多张XPU卡上，可以看做Gather + Broadcast的操作组合，它的反向操作对应ReduceScatter，其最应用场景有：\nAllGather可应用于模型并行；\n模型并行里前向计算里的参数全同步，需要用allgather把模型并行里将切分到不同的XPU上的参数全同步到一张XPU上才能进行前向计算。\n6 All Reduce AllReduce属于多对多的通信原语，具有多个数据发送者，多个数据接收者，其在集群内的所有节点上都执行相同的Reduce操作，可以将集群内所有节点的数据规约运算得到的结果发送到所有的节点上。AllReduce操作可通过在主节点上执行Reduce + Broadcast或ReduceScatter + AllGather实现，如下图所示：先在主节点上执行reduce得到规约累加和26，再把这个累加和26 broadcast到其他的节点，这样整个集群内，每个节点的数值就都保持一致。\nAllReduce是数据的多对多的规约运算，它将所有的XPU卡上的数据规约（比如SUM求和）到集群内每张XPU卡上，其应用场景有：\nAllReduce应用于数据并行；\n数据并行各种通信拓扑结构比如Ring allReduce、Tree allReduce里的 allReduce操作；\n7 Reduce Scatter ReduceScatter属于多对多的通信原语，具有多个数据发送者，多个数据接收者，其在集群内的所有节点上都按维度执行相同的Reduce规约运算，再将结果发散到集群内所有的节点上，Reduce-scatter等价于节点个数次的reduce规约运算操作，再后面执行节点个数的scatter次操作，其反向操作是AllGather。\n如下图所示，先reduce操作 XPU 0-3的数据reduce为A(A0+A1+A2+A3) + B(B0 + B1 +B2 + B3) + C(C0 + C1 + C2 + C3) + D(D0 + D1 + D2 + D3 ) 到一张XPU上，再进行分片scatter到集群内所有的XPU卡上。\nReduceScatter是数据的多对多的reduce + scatter运算，它将所有的XPU卡上的数据先规约（比如SUM求和）到1张XPU卡上，再进行scatter，其应用场景有：\nReduceScatter即可应用于数据并行也可应用于模型并行；\n数据并行allReduce里的 ReduceScatter+ Allgather组合里的ReduceScatter操作；\n模型并行里在前向allgather后的反向计算里的ReduceScatter；\n8 All to All All-To-All操作每一个节点的数据会scatter到集群内所有节点上，同时每一个节点也会Gather集群内所有节点的数据。ALLTOALL是对ALLGATHER的扩展，区别是ALLGATHER 操作中，不同节点向某一节点收集到的数据是相同的，而在ALLTOALL中，不同的节点向某一节点收集到的数据是不同的，如下图所示\nAllToAll是数据的多对多的转置，它将所有张XPU卡上的数据转置到所有的XPU卡上，其主要应用场景有：\nAllToAll应用于模型并行；\n模型并行里的矩阵转置；\n数据并行到模型并行的矩阵转置；\n","permalink":"https://www.zzudongxiang.com/posts/collective-communication-primitives/","summary":"\u003cdiv\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cspan style=\"font-size: 16px; color: rgb(51, 51, 51)\"\u003e参考来源: \u003c/span\u003e\u003ca href=\"https://zhuanlan.zhihu.com/p/493092647\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e分布式训练常用的集合通信及其通信原语\u003c/span\u003e\u003c/a\u003e\u003cspan style=\"font-size: 16px; color: rgb(51, 51, 51)\"\u003e, \u003c/span\u003e\u003ca href=\"https://zhuanlan.zhihu.com/p/496105041\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e分布式训练常用的网络结构及集合通信拓扑算法\u003c/span\u003e\u003c/a\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cimg src=\"images/image-eimu.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003cp\u003e\u003cspan style=\"font-size: 16px; color: rgb(51, 51, 51)\"\u003e图片来源：\u003c/span\u003e\u003ca href=\"https://images.nvidia.com/content/volta-architecture/pdf/volta-architecture-whitepaper.pdf\"\u003evolta-architecture-whitepaper\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"1-broadcast\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1 Broadcast\u003c/span\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eBroadcast属于\u003c/span\u003e\u003cstrong\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1对多\u003c/span\u003e\u003c/strong\u003e\u003cspan fontsize=\"\" color=\"\"\u003e的通信原语，一个数据发送者，多个数据接收者，可以在集群内把一个节点自身的数据广播到其他节点上。如下图所示，圈圈表示集群中的训练加速卡节点，相同的颜色的小方块则代表相同的数据。当主节点 0 执行Broadcast时，数据即从主节点0被广播至其他节点。\u003c/span\u003e\u003c/p\u003e\n\u003cimg src=\"images/image-mgng.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eBroadcast是数据的1对多的同步，它将一张XPU卡上的数据同步到其他所有的XPU卡上，其应用场景有：\u003c/span\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e数据并行的参数初始化，确保每张卡上的初始参数是一致的；\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eallReduce里的 broadcast + reduce组合里的broadcast操作；\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e分布式训练parameter server 参数服务器结构里的 master节点 broadcast 数据到worker节点，再从worker节点reduce数据回master节点里的broadcast操作；\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-scatter\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e2 Scatter\u003c/span\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e同Broadcast一样，Scatter也是一个1对多的通信原语，也是一个数据发送者，多个数据接收者，可以在集群内把一个节点自身的数据发散到其他节点上。与Broadcast不同的是Broadcast把主节点0的数据发送给所有节点，而Scatter则是将数据的进行切片再分发给集群内所有的节点，如下图所示，不相同的颜色的小方块代表不相同的数据，主节点 0 将数据分为四份分发到了节点0-3。\u003c/span\u003e\u003c/p\u003e\n\u003cimg src=\"images/image-jcjv.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eScatter是数据的1对多的分发，它将一张XPU卡上的数据进行分片再分发到其他所有的XPU卡上，他的反向操作对应Gather，其应用场景有：\u003c/span\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eReduceScatter组合里的 Scatter操作；\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e模型并行里初始化时将模型scatter到不同的XPU上；\u003c/span\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"3-gather\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e3 Gather\u003c/span\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eGather操作属于\u003c/span\u003e\u003cstrong\u003e\u003cspan fontsize=\"\" color=\"\"\u003e多对1\u003c/span\u003e\u003c/strong\u003e\u003cspan fontsize=\"\" color=\"\"\u003e的通信原语，具有多个数据发送者，一个数据接收者，可以在集群内把多个节点的数据收集到一个节点上，如下图所示，不相同的颜色的小方块代表不相同的数据。\u003c/span\u003e\u003c/p\u003e\n\u003cimg src=\"images/image-clhx.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eGather是数据的多对1的收集，它将多张XPU卡上的数据收集到1张XPU卡上，它的反向操作对应Scatter，其应用场景有：\u003c/span\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cspan fontsize=\"\" color=\"\"\u003eReduceScatter组合里的 Scatter操作；\u003c/span\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"4-reduce\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e4 Reduce\u003c/span\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eReduce属于\u003c/span\u003e\u003cstrong\u003e\u003cspan fontsize=\"\" color=\"\"\u003e多对1\u003c/span\u003e\u003c/strong\u003e\u003cspan fontsize=\"\" color=\"\"\u003e的通信原语，具有多个数据发送者，一个数据接收者，可以在集群内把多个节点的数据\u003c/span\u003e\u003cstrong\u003e\u003cspan fontsize=\"\" color=\"\"\u003e规约运算\u003c/span\u003e\u003c/strong\u003e\u003cspan fontsize=\"\" color=\"\"\u003e到一个主节点上，常用的规约操作符有：求累加和SUM、求累乘积PROD、求最大值MAX、求最小值MIN、逻辑与 LAND、按位与BAND、逻辑或LOR、按位或BOR、逻辑异或LXOR、按位异或BOXR、求最大值和最小大的位置MAXLOC、求最小值和最小值的位置MINLOC等，这些规约运算也需要加速卡支持对应的算子才能生效。\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eReuduce操作从集群内每个节点上获取一个输入数据，通过规约运算操作后，得到精简数据，如下图的SUM求累加和：节点0数值 5、节点1数值6、节点2数值7、节点3数值8，经过SUM运算后 累积和为 26，即得到更为精简的数值，在reduce原语里回会去调用 reduce SUM算子来完成这个求和累加。\u003c/span\u003e\u003c/p\u003e\n\u003cimg src=\"images/image-mxqm.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eReduce是数据的多对1的规约运算，它将所有张XPU卡上的数据规约（比如SUM求和）到1张XPU卡上，其应用场景有：\u003c/span\u003e\u003c/p\u003e","title":"集合通信-通信原语"},{"content":" 1. 快速使用 HCCL（Huawei Collective Communication Library）是基于昇腾AI处理器的高性能集合通信库，其主要功能与作用与Nvidia的NCCL库相似，主要用于集合通信，CANN库种自带一套测试工具用以分析集合通信性能。\n1.1 编译环境配置 前置环境配置阶段请参考Llama2部署记录，后续的所有流程均需要在具备HCCL硬件的平台上实现，需要注意的是，建议使用的Ubuntu版本大于等于20.04LTS，否则可能会遇到VSCode不支持的情况。\nA. CANN CANN的配置过程参考Llama2部署记录文档的4. 安装CANN章节，并记录安装位置，以备后续使用\n完成CANN后，建议在~/.bashrc文件中添加对应的环境变量，例如：\n# 使用nano打开~/.bashrc文件 nano ~/.bashrc 在文件的最后添加export ASCEND_HOME=/usr/local/Ascend/ascend-toolkit/latest\nB. OpenMPI 在OpenMPI官网找到对应版本的安装包下载，然后解压缩安装包，以mpich-4.2.0版本为例：\n# mpich下载链接参考：https://www.mpich.org/static/downloads wget https://www.mpich.org/static/downloads/4.2.0/mpich-4.2.0.tar.gz # 解压缩mpich压缩包 tar -zxvf mpich-4.2.0.tar.gz 配置mpi的安装路径，以/root/mpich路径为例：\n# 新建文件夹 mkdir ~/mpich # 进入解压缩后的mpich文件夹 cd mpich-4.2.0 # 配置安装路径 ./configure -prefix=/root/mpich --disable-fortran 使用make命令构建mpich的可执行文件，该过程可能耗时比较长\nmake make install 完后后将mpich添加到环境变量种，并添加对应的链接库和帮助文件\n# 修改~/.bashrc文件 nano ~/.bashrc 在最后一行添加以下内容：\nexport MPI_HOME=/root/mpich\nexport PATH=$MPI_HOME/bin:$PATH\nexport MANPATH=$MPI_HOME/man:$MANPATH\nexport LD_LIBRARY_PATH=$MPI_HOME/lib:$LD_LIBRARY_PATH\n1.2 文件编译 本章节参考链接：【昇腾】Ascend Snt9B集合通信算子单机多卡性能测试指导\n为了方便后续修改hccl_test内的文件，且保持一份未修改的源文件，建议将对应的文件复制到用户路径下，例如复制到/root/Workdir路径下\ncp -r /usr/local/Ascend/ascend-toolkit/7.0.0/tools/hccl_test /root/Workdir/ 由于配置的ASCEND_HOME指向的文件夹是一个链接，在复制hccl_test文件夹的时候需要复制源文件而不是文件夹链接，因此可以通过命令查看其对应的真实文件路径\n# 切换到ASCEND_HOME路径 cd $ASCEND_HOME/tools # 查看链接的真实地址 ll 切换到复制后的文件夹后，执行编译命令：\n# 切换到复制后的文件夹中 cd /root/Workdir/hccl_test # 编译文件 make MPI_HOME=/home/mpich ASCEND_DIR=/usr/local/Ascend/ascend-toolkit/latest 编译完成后会在新建的./bin文件夹中出现多个*_test可执行文件\n1.3 运行测试案例 执行以下命令即可进行简单测试：\n# mpirun -n 8 * 表示使用mpi拉起8个进程，建议与最后的-p参数保持一致 mpirun -n 8 ./bin/all_reduce_test -b 8 -e 2048M -f 2 -p 8 对应的测试配置参数及其释义如下：\n-b,--minbytes \u0026lt;min size in bytes\u0026gt; -e,--maxbytes \u0026lt;max size in bytes\u0026gt; -i,--stepbytes \u0026lt;increment size\u0026gt; -f,--stepfactor \u0026lt;increment factor\u0026gt; -n,--iters \u0026lt;iteration count\u0026gt; -o,--op \u0026lt;sum/prod/min/max\u0026gt; -d,--datatype \u0026lt;int8/int16/int32/fp16/fp32/int64/uint64/uint8/uint16/uint32/fp64/bfp16\u0026gt; -r,--root \u0026lt;root\u0026gt; -w,--warmup_iters \u0026lt;warmup iteration count\u0026gt; -c,--check \u0026lt;result verification\u0026gt; 0:disabled 1:enabled. -p,--npus \u0026lt;npus used for one node\u0026gt; -h,--help 如果需要修改HCCL通信的缓冲区大小（每次HCCL通信可发送/接收的数据包大小），可以在执行之前设置环境变量HCCL_BUFFSIZE，单位MB，例如设置缓冲区大小为2GB：\nexport HCCL_BUFFSIZE=2048 2. 调试环境配置 为了方便调试和分析hccl_test编写的测试工具在运行中各个参数与之对应的实际生效作用关系，需要配置调试环境进行单步调试，通过抓取运行中的寄存器值可以看到每个参数实际对应的功能。\n2.1 VSCode设置 VSCode需要安装Remote-SSH插件连接到远程服务器，插件安装过程参考其他教程，在使用Remote-SSH插件连接到远程服务器后需要在远程服务器上安装C/C++、Jupyter、Python等扩展\n使用Remote-SSH登录到服务器上的指定文件夹，并新建.vscode文件夹，并在该文件夹下新建以下三个配置文件c_cpp_properties.json、launch.json、tasks.json\nA. c_cpp_properties.json 该文件主要用于配置在编辑器中是否显示静态检查结果，例如部分头文件无法找到会出现红色波浪等\n{ \u0026quot;env\u0026quot;:{ \u0026quot;ASCEND_HOME\u0026quot;: \u0026quot;/usr/local/Ascend/ascend-toolkit/latest\u0026quot; }, \u0026quot;configurations\u0026quot;: [ { \u0026quot;name\u0026quot;: \u0026quot;linux-gcc-arm64\u0026quot;, \u0026quot;includePath\u0026quot;: [ \u0026quot;${workspaceFolder}\u0026quot;, \u0026quot;${workspaceFolder}/common/src\u0026quot;, \u0026quot;${workspaceFolder}/common/utils\u0026quot;, \u0026quot;${workspaceFolder}/opbase_test\u0026quot;, \u0026quot;${MPI_HOME}/include\u0026quot;, \u0026quot;${ASCEND_HOME}/include\u0026quot; ], \u0026quot;defines\u0026quot;: [ \u0026quot;MEM_DUMP\u0026quot; ], \u0026quot;compilerPath\u0026quot;: \u0026quot;/usr/bin/gcc\u0026quot;, \u0026quot;cStandard\u0026quot;: \u0026quot;c11\u0026quot;, \u0026quot;cppStandard\u0026quot;: \u0026quot;gnu++11\u0026quot;, \u0026quot;intelliSenseMode\u0026quot;: \u0026quot;linux-gcc-arm64\u0026quot;, \u0026quot;mergeConfigurations\u0026quot;: false } ], \u0026quot;version\u0026quot;: 4 } includePath：将代码所需的头文件路径添加到该字段下即可 B. launch.json 该文件主要用于配置调试器，在调试C/C++工具时需要先安装gdb工具，安装命令：apt install gdb\n{ \u0026quot;configurations\u0026quot;: [ { \u0026quot;name\u0026quot;: \u0026quot;C/C++: gcc 生成和调试活动文件\u0026quot;, \u0026quot;type\u0026quot;: \u0026quot;cppdbg\u0026quot;, \u0026quot;request\u0026quot;: \u0026quot;launch\u0026quot;, \u0026quot;program\u0026quot;: \u0026quot;${workspaceFolder}/bin/zhangdx_test\u0026quot;, \u0026quot;args\u0026quot;: [], \u0026quot;stopAtEntry\u0026quot;: false, \u0026quot;cwd\u0026quot;: \u0026quot;${workspaceFolder}\u0026quot;, \u0026quot;environment\u0026quot;: [], \u0026quot;externalConsole\u0026quot;: false, \u0026quot;MIMode\u0026quot;: \u0026quot;gdb\u0026quot;, \u0026quot;setupCommands\u0026quot;: [ { \u0026quot;description\u0026quot;: \u0026quot;为 gdb 启用整齐打印\u0026quot;, \u0026quot;text\u0026quot;: \u0026quot;-enable-pretty-printing\u0026quot;, \u0026quot;ignoreFailures\u0026quot;: true }, { \u0026quot;description\u0026quot;: \u0026quot;将反汇编风格设置为 Intel\u0026quot;, \u0026quot;text\u0026quot;: \u0026quot;-gdb-set disassembly-flavor intel\u0026quot;, \u0026quot;ignoreFailures\u0026quot;: true } ], \u0026quot;preLaunchTask\u0026quot;: \u0026quot;C/C++: gcc 生成活动文件\u0026quot;, \u0026quot;miDebuggerPath\u0026quot;: \u0026quot;/usr/bin/gdb\u0026quot;, \u0026quot;envFile\u0026quot;: \u0026quot;${workspaceFolder}/.env\u0026quot; } ], \u0026quot;version\u0026quot;: \u0026quot;2.0.0\u0026quot; } program：编译后生成的可执行文件，编译参数见tasks.json文件\nenvFile：程序运行时添加的环境变量，可参考.env文件\npreLaunchTask：编译可执行文件的参数配置，参考tasks.json文件\nC. tasks.json 该文件主要用于编译生成可执行文件，相关的编译参数需要添加到该文件中，参数信息参考Makefile文件\n{ \u0026quot;tasks\u0026quot;: [ { \u0026quot;type\u0026quot;: \u0026quot;cppbuild\u0026quot;, \u0026quot;label\u0026quot;: \u0026quot;C/C++: gcc 生成活动文件\u0026quot;, \u0026quot;command\u0026quot;: \u0026quot;/usr/bin/gcc\u0026quot;, \u0026quot;args\u0026quot;: [ \u0026quot;-Wl,--copy-dt-needed-entries\u0026quot;, \u0026quot;-fdiagnostics-color=always\u0026quot;, \u0026quot;${workspaceFolder}/common/utils/**.cc\u0026quot;, \u0026quot;${workspaceFolder}/common/src/**.cc\u0026quot;, \u0026quot;-g\u0026quot;, \u0026quot;${workspaceFolder}/opbase_test/zhangdx_test.cc\u0026quot;, \u0026quot;-o\u0026quot;, \u0026quot;${workspaceFolder}/bin/zhangdx_test\u0026quot;, \u0026quot;-I${workspaceFolder}/common/src\u0026quot;, \u0026quot;-I${workspaceFolder}/common/utils\u0026quot;, \u0026quot;-I${workspaceFolder}/opbase_test\u0026quot;, \u0026quot;-I${MPI_HOME}/include\u0026quot;, \u0026quot;-I${ASCEND_HOME}/include\u0026quot;, \u0026quot;-L${MPI_HOME}/lib\u0026quot;, \u0026quot;-L${ASCEND_HOME}/lib64\u0026quot;, \u0026quot;-lhccl\u0026quot;, \u0026quot;-lascendcl\u0026quot;, \u0026quot;-lmpi\u0026quot;, \u0026quot;-DMEM_DUMP\u0026quot; ], \u0026quot;options\u0026quot;: { \u0026quot;cwd\u0026quot;: \u0026quot;${fileDirname}\u0026quot; }, \u0026quot;problemMatcher\u0026quot;: [ \u0026quot;$gcc\u0026quot; ], \u0026quot;group\u0026quot;: \u0026quot;build\u0026quot;, \u0026quot;detail\u0026quot;: \u0026quot;调试器生成的任务\u0026quot; } ], \u0026quot;version\u0026quot;: \u0026quot;2.0.0\u0026quot; } label：与launch.json文件中的preLaunchTask字段对应\nargs：编译参数，具体参考Makefile文件\n2.2 msprof设置 本章节参考：采集昇腾AI处理器系统数据，可以根据文档内容直接运行对应的执行参数，但是为了方便程序运行与调试，请参考8卡Trace采集脚本\n运行脚本后会在./log/prof/*.json路径中出现对应的timeline文件，打开Perfetto网站，导入对应的json文件即可查看和分析对应的测试Trace\n2.3 点对点数据抓取 点对点NPU测试（数据交换）测试速度比msprof抓取Trace快，可以测试不同数据包下的性能表现，测试脚本参考点对点测试脚本\n3. 多机通信测试 本章节未进行验证，相关内容参考CANN库中自带的教程\n多机集群训练时，需配置环境变量指定host网卡：（HCCL_SOCKET_IFNAME） # 配置HCCL的初始化root通信网卡名，HCCL可通过该网卡名获取Host IP，完成通信域创建。 # 支持以下格式配置：(4种规格自行选择1种即可) # export HCCL_SOCKET_IFNAME=eth,enp ：使用所有以eth或enp前缀的网卡，比如eth1,eth2,enp1… # export HCCL_SOCKET_IFNAME==eth,enp ：使用eth或enp的网卡 # export HCCL_SOCKET_IFNAME=^eth,enp ：不要使用任何以eth或enp前缀的网卡 # export HCCL_SOCKET_IFNAME=^=eth,enp ：不要使用eth或enp网卡 注：网卡名仅为举例说明，并不只对eth,enp网卡生效 多机集群训练时，需统计所有节点使用的host网卡信息： # 编辑全部参与训练的节点ip:每节点的进程数 nano hostfile # 10.78.130.22:8 # 10.78.130.21:8 # ... 多节点运行：（两节点为例） mpirun -f hostfile -n 16 ./bin/all_reduce_test -b 8K -e 64M -f 2 -d fp32 -o sum -p 8 ","permalink":"https://www.zzudongxiang.com/posts/hccl-test-environment/","summary":"\u003cdiv\u003e\n\u003ch2 id=\"1-快速使用\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1. 快速使用\u003c/span\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eHCCL（Huawei Collective Communication Library）是基于昇腾AI处理器的高性能集合通信库，其主要功能与作用与Nvidia的NCCL库相似，主要用于集合通信，CANN库种自带一套测试工具用以分析集合通信性能。\u003c/span\u003e\u003c/p\u003e\n\u003ch3 id=\"11-编译环境配置\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003e1.1 编译环境配置\u003c/span\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e前置环境配置阶段请参考\u003c/span\u003e\u003ca href=\"https://git.zzudongxiang.com/pcl.cloudbrain.project/mindspore.llama2/src/branch/main/README.md\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003eLlama2部署记录\u003c/span\u003e\u003c/a\u003e\u003cspan fontsize=\"\" color=\"\"\u003e，后续的所有流程均需要在具备HCCL硬件的平台上实现，需要注意的是，建议使用的Ubuntu版本大于等于20.04LTS，否则可能会遇到VSCode不支持的情况。\u003c/span\u003e\u003c/p\u003e\n\u003ch4 id=\"a-cann\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003eA. CANN\u003c/span\u003e\u003c/h4\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003eCANN的配置过程参考\u003c/span\u003e\u003ca href=\"https://git.zzudongxiang.com/pcl.cloudbrain.project/mindspore.llama2/src/branch/main/README.md\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003eLlama2部署记录\u003c/span\u003e\u003c/a\u003e\u003cspan fontsize=\"\" color=\"\"\u003e文档的\u003c/span\u003e\u003cstrong\u003e\u003cspan fontsize=\"\" color=\"\"\u003e4. 安装CANN\u003c/span\u003e\u003c/strong\u003e\u003cspan fontsize=\"\" color=\"\"\u003e章节，并记录安装位置，以备后续使用\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e完成CANN后，建议在\u003c/span\u003e\u003ccode\u003e~/.bashrc\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e文件中添加对应的环境变量，例如：\u003c/span\u003e\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e # 使用nano打开~/.bashrc文件\n nano ~/.bashrc\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e在文件的最后添加\u003c/span\u003e\u003ccode\u003eexport ASCEND_HOME=/usr/local/Ascend/ascend-toolkit/latest\u003c/code\u003e\u003c/p\u003e\n\u003ch4 id=\"b-openmpi\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003eB. OpenMPI\u003c/span\u003e\u003c/h4\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e在\u003c/span\u003e\u003ca href=\"https://www.mpich.org/\"\u003e\u003cspan fontsize=\"\" color=\"\"\u003eOpenMPI官网\u003c/span\u003e\u003c/a\u003e\u003cspan fontsize=\"\" color=\"\"\u003e找到对应版本的安装包下载，然后解压缩安装包，以\u003c/span\u003e\u003ccode\u003empich-4.2.0\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e版本为例：\u003c/span\u003e\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e # mpich下载链接参考：https://www.mpich.org/static/downloads\n wget https://www.mpich.org/static/downloads/4.2.0/mpich-4.2.0.tar.gz\n # 解压缩mpich压缩包\n tar -zxvf mpich-4.2.0.tar.gz\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e配置mpi的安装路径，以\u003c/span\u003e\u003ccode\u003e/root/mpich\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e路径为例：\u003c/span\u003e\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e # 新建文件夹\n mkdir ~/mpich\n # 进入解压缩后的mpich文件夹\n cd mpich-4.2.0\n # 配置安装路径\n ./configure -prefix=/root/mpich --disable-fortran\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e使用\u003c/span\u003e\u003ccode\u003emake\u003c/code\u003e\u003cspan fontsize=\"\" color=\"\"\u003e命令构建mpich的可执行文件，该过程可能耗时比较长\u003c/span\u003e\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e make\n make install\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e完后后将mpich添加到环境变量种，并添加对应的链接库和帮助文件\u003c/span\u003e\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e # 修改~/.bashrc文件\n nano ~/.bashrc\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cspan fontsize=\"\" color=\"\"\u003e在最后一行添加以下内容：\u003c/span\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eexport MPI_HOME=/root/mpich\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eexport PATH=\u003c/code\u003e$MPI_HOME/bin:$\u003ccode\u003ePATH\u003c/code\u003e\u003c/p\u003e","title":"HCCL集合通信测试环境设置"},{"content":" 1. 创建docker 1.1 docker命令 显示全部的镜像：docker images\n创建一个容器：docker run ...\u0026lt;查看1.2节内容\u0026gt;\n显示全部的容器：docker ps -a\n启动一个容器：docker start \u0026lt;id\u0026gt;\n停止一个容器：docker stop \u0026lt;id\u0026gt;\n进入一个正在运行的程序：docker exec -it \u0026lt;id\u0026gt; /bin/bash\n删除一个容器：docker rm \u0026lt;id\u0026gt;\n1.2 创建容器 创建一个docker容器的时候需要同时挂载本地工作目录和相关的程序驱动，因此创建docker容器的命令参数较多，以下为一个创建docker容器命令的基本格式：\ndocker run -it --ipc=host --name \u0026lt;name\u0026gt; -v \u0026lt;local_path\u0026gt;:\u0026lt;docker_path\u0026gt; \\ --workdir=\u0026lt;docker_path\u0026gt; \\ --pids-limit 409600 \\ --privileged --network=host \\ --shm-size=128G \\ --device=/dev/davinci0 \\ --device=/dev/davinci1 \\ --device=/dev/davinci2 \\ --device=/dev/davinci3 \\ --device=/dev/davinci4 \\ --device=/dev/davinci5 \\ --device=/dev/davinci6 \\ --device=/dev/davinci7 \\ --device=/dev/davinci_manager \\ --device=/dev/devmm_svm \\ --device=/dev/hisi_hdc \\ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \\ -v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \\ -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ \\ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \\ -v /usr/local/dcmi:/usr/local/dcmi \\ -v /etc/ascend_install.info:/etc/ascend_install.info \\ -v /etc/bashrc:/etc/bashrc \\ -p 223:223 \\ -p 224:6006 \\ -p 225:8080 \\ -p 226:8888 \\ -u root \\ \u0026lt;image_id\u0026gt; /bin/bash -it：已交互方式运行容器，并分配一个终端\n-ipc=host：用于docker内部进程与宿主机进程的通信\n--name \u0026lt;name\u0026gt;：指定要创建的容器的名字\n-v \u0026lt;local_path\u0026gt;:\u0026lt;docker_path\u0026gt;：挂载本地的\u0026lt;local_path\u0026gt;路径到容器中的\u0026lt;docker_path\u0026gt;路径\n--workdir=\u0026lt;docker_path\u0026gt;：重定向容器的工作路径到\u0026lt;docker_path\u0026gt;路径\n--pids-limit 409600：\u0026lt;可省略\u0026gt;对容器内可以运行的进程数量限制\n--privileged：使容器内的root具有容器外部root的权限\n--network=host：\u0026lt;删除\u0026gt;指定容器的网络与宿主机相同\n--shm-size=128G：\u0026lt;可省略\u0026gt;修改共享内存的大小\n--device=\u0026lt;device\u0026gt;：挂载硬件设备\n-v /usr/local/Ascend/driver:/usr/local/Ascend/driver：\n\\[**NPU**\\]挂载NPU驱动\n-v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware：\n\\[**NPU**\\]挂载Firmware\n-v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/：\n\\[**NPU**\\]挂载NPU工具包\n-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi：\n\\[**NPU**\\]挂载npu-smi命令\n-v /usr/local/dcmi:/usr/local/dcmi：\n\\[**NPU**\\]挂载DCMI\n-v /etc/ascend_install.info:/etc/ascend_install.info：\n\\[**NPU**\\]挂载安装信息\n-v /etc/bashrc:/etc/bashrc：添加bash命令行的内容\n-p 223:223：挂载端口，用于使用ssh直接登录docker容器内部\n-p 224:6006：挂载端口，将TensorBoard端口映射到宿主\n-p 225:8080：挂载端口，将MindInsight端口映射到宿主\n-p 226:8888：挂载端口，将Jupyter端口映射到宿主\n-u root：以root身份进入容器\n\u0026lt;image_id\u0026gt;：要创建容器的镜像ID，可通过docker images查看\n/bin/bash：进入容器后执行的命令，默认进入控制台\n在Ascend上使用的镜像信息为：ascendhub.huawei.com/public-ascendhub/all-in-one\n完成容器创建后可以通过npu-smi info命令查看NPU状态是否正常，若NPU正常挂载，则会输出NPU的数量、状态等基本信息。\n1.3 创建实例 docker run -it --ipc=host --name zhangdx -v ~/workdir:/root \\ --workdir=/root \\ --privileged \\ --device=/dev/davinci0 \\ --device=/dev/davinci1 \\ --device=/dev/davinci2 \\ --device=/dev/davinci3 \\ --device=/dev/davinci4 \\ --device=/dev/davinci5 \\ --device=/dev/davinci6 \\ --device=/dev/davinci7 \\ --device=/dev/davinci_manager \\ --device=/dev/devmm_svm \\ --device=/dev/hisi_hdc \\ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \\ -v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \\ -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ \\ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \\ -v /usr/local/dcmi:/usr/local/dcmi \\ -v /etc/ascend_install.info:/etc/ascend_install.info \\ -v /etc/bashrc:/etc/bashrc \\ -u root \\ -p 223:223 \\ -p 224:6006 \\ -p 225:8080 \\ -p 226:8888 \\ 47f84079ea47 /bin/bash 2. 配置SSH 为了使用外部IDE（VSCode或MindStudio等）连接Docker内的编译环境，需要使用SSH将容器内的操作系统通过SSH映射到外部\n2.1 安装SSH-Server 需要安装SSH Server，并修改管理员密码，或配置SSH-Key登录的方式登录到Docker内部\n# 更新apt apt update # 安装SSH-Server和Nano编辑器 apt install -y nano openssh-server 2.2 修改SSH配置 使用如下命令修改Docker内部root用户的密码\npasswd # 修改成功后会有如下显示 # passwd: password updated successfully 使用nano（也可以使用vi）修改ssh的配置信息\nnano /etc/ssh/sshd_config 新增Port 223，这里的端口号应该与创建容器时的一致\n新增PermitRootLogin yes\n新增PubkeyAuthentication yes\n新增ClientAliveInterval 30，设置与客户端之间的心跳包间隔\n新增ClientAliveCountMax 10\n然后使用如下命令启动ssh并查看ssh的状态\n# 启动ssh service ssh start # 查看ssh的状态 service ssh status 2.3 添加SSH密钥 为了方便后续使用IDE连接docker，建议配置SSH密钥以实现免密登录，使用ssh-keygen命令在本地生成公钥和私钥，并将公钥的内容复制到Docker内\nnano ~/.ssh/authorized_keys 2.4 添加环境变量 在使用ssh直接连接到docker内时，npu-smi info命令可能出现无法使用的情况，可根据错误提示按照如下方法解决该问题\nnpu-smi: error while loading shared libraries: libdrvdsmi_host.so: cannot open shared object file: No such file or directory\n如果出现该错误是因为相关的环境变量未成功添加到终端，可按照如下方法添加\n# 使用nano修改~/.bashrc文件 nano ~/.bashrc # 在最后一行添加如下内容 source /usr/local/Ascend/ascend-toolkit/set_env.sh npu-smi: error while loading shared libraries: libdrvdsmi_host.so: cannot open shared object file: No such file or directory\n如果出现该错误是NPU驱动相关的环境变量未添加，可按照如下方法添加\n# 查找文件所在的路径 find / -name libdrvdsmi_host.so # 将文件路径添加到环境变量中 export LD_LIBRARY_PATH=/usr/local/Ascend/driver/lib64/driver/:$LD_LIBRARY_PATH 为了方便在每一次打开终端时都可以正常运行npu-smi指令，可以将以上内容添加到~/.bashrc文件中\n# 编辑~/.bashrc文件 nano ~/.bashrc 添加source /usr/local/Ascend/ascend-toolkit/set_env.sh\n添加source /usr/local/Ascend/driver/bin/setenv.bash\n添加export PATH=/usr/local/Ascend/driver/tools/:$PATH\n添加export LD_LIBRARY_PATH=/usr/local/Ascend/add-ons/:$LD_LIBRARY_PATH\n完成添加后，使用source ~/.bashrc命令重新装载.bashrc文件生效\n3. 安装Anaconda 为了解决多种模型和MindSpore对Python版本的需求不一致的问题，安装安装Anaconda创建虚拟Python环境解决该问题。\n3.1 下载Anaconda 进入Anaconda的官网获取最新版本的conda安装链接，并如下命令安装Anaconda\n下载Anaconda时需要注意对应的版本号和芯片架构类型，例如在Ascend上就是ARM64架构\n# 从官网获取下载链接：https://www.anaconda.com/download#downloads wget https://repo.anaconda.com/archive/Anaconda3-xxx.sh # 安装Anaconda bash Anaconda3-xxx.sh # 刷新环境变量，否则无法启用conda命令 source ~/.bashrc 在Ascend上下载的版本为：Anaconda3-2024.02-1-Linux-aarch64.sh\n3.2 常见命令 查看全部的环境：conda env list\n激活指定环境：conda activate \u0026lt;name\u0026gt;\n创建新的环境：conda create -n \u0026lt;name\u0026gt; python=\u0026lt;3.7.11\u0026gt;\n删除指定环境：conda remove -n \u0026lt;name\u0026gt; --all\n3.3 创建环境 使用如下命令创建一个名为mindspore的Python环境，后续的所有操作都在该环境下进行\n# 创建适用于mindspore的虚拟环境（如果已经存在则无需重复创建） conda create -n mindspore python=3.7.11 # 进入虚拟环境 conda activate mindspore 4. 安装CANN 安装CANN之前需要确保NPU的驱动和固件已经完成安装，此步骤一般宿主机已完成，通过docker挂载到容器内部，可以正常使用\n4.1 设备检查 首先使用如下命令确定NPU已成功挂载到服务器上\nlspci | grep accelerators 在昇腾社区中搜索对应的CANN版本，并下载，选择版本时请选择开发套件toolkit，文件格式为*.run，下载完成后使用FTP或SFTP等工具将文件传输至服务器中\n4.2 安装依赖 在安装CANN之前需要安装一些必要的工具包，安装命令如下所示（以Ubuntu系统为例）\n# 安装必备组件 apt install -y nano gcc g++ make cmake zlib1g zlib1g-dev openssl libsqlite3-dev libssl-dev libffi-dev unzip pciutils net-tools libblas-dev gfortran libblas3 使用python --version检查Python的版本，根据官网的要求，CANN要求的Python版本范围是：python3.7.5~3.7.11、python3.8.0~3.8.11、python3.9.0~3.9.7和python3.10.0~3.10.12，如果Python版本不匹配，则需要使用Anaconda创建对应版本的虚拟环境。\n使用pip安装必要的依赖包：\npip install attrs numpy decorator sympy cffi pyyaml pathlib2 psutil protobuf scipy requests absl-py wheel typing_extensions 4.3 安装CANN 将下载的*.run文件通过FTP或SFTP等方式上传到服务器上，然后按照如下命令安装CANN开发包\n# 修改文件的可执行权限 chmod +x ./Ascend-cann-toolkit_7.0.0_linux-aarch64.run # 开始安装CANN工具包 ./Ascend-cann-toolkit_7.0.0_linux-aarch64.run --install # 配置环境变量 source /usr/local/Ascend/ascend-toolkit/set_env.sh 这里使用的CANN版本为7.0.0，在选择版本时需要与MindSpore版本一致，也需要与Mindformers版本一致，否则将导致不可预料的问题。CANN与MindSpore版本匹配查询网站\n5. 安装Mindspore 由于Llama2模型原生使用NCCL（NVIDIA Collective Communications Library）技术，这将导致在Ascend平台上无法正常的运行原生模型，因此需要使用Mindspore Mindformers框架下修改的Llama2模型。\n5.1 使用pip安装 Mindspore可以使用pip直接安装，安装过程参考Mindspore，pip安装的Mindspore版本参考如该网站\n# 从以下网站获取对应的pip包网址 # https://www.mindspore.cn/versions wget https://ms-release.obs.cn-north-4.myhuaweicloud.com/2.2.11/MindSpore/unified/aarch64/mindspore-2.2.11-cp37-cp37m-linux_aarch64.whl # 使用pip安装 pip install mindspore-2.2.11-cp37-cp37m-linux_aarch64.whl 这里选择最新版Mindspore（2.2.11版本），硬件平台是Ascend910_Linux-aarch64的Python3.7版本的安装链接\n5.2 使用源码安装 不建议使用源码安装Mindspore，仓库内的版本号与CANN、Mindformers等容易发生不兼容问题，但是也可以根据官方教程安装Mindspore\n5.3 验证安装结果 使用如下命令验证Mindspore的安装结果\npython -c \u0026quot;import mindspore;mindspore.set_context(device_target='Ascend');mindspore.run_check()\u0026quot; 6. 安装Mindformers 6.1 使用pip安装 在官方安装页面找到与Mindspore版本一致的Mindformers安装包，下载并安装即可\n# 下载Mindformers wget https://ms-release.obs.cn-north-4.myhuaweicloud.com/2.2.11/MindFormers/any/mindformers-1.0.0-py3-none-any.whl # 安装Mindformers pip install mindformers-1.0.0-py3-none-any.whl 6.2 使用源码安装 可以使用git下载Mindformers的源码，然后使用自带的构建工具构建Mindformers环境，但是由于版本依赖问题，不是很推荐使用这种方法，可以使用pip安装对应版本的包\n# 下载Mindformers git clone -b dev https://gitee.com/mindspore/mindformers.git # 安装Mindformers cd mindformers bash build.sh 7. 安装Mindinsight Mindinsight可以帮助分析使用Mindspore构建的应用的性能等信息，使用教程参考官方连接\n7.1 使用pip安装 使用pip直接安装Mindinsight即可，但是需要注意其版本应与Mindspore版本一致\n# 使用pip安装Mindinsight pip install mindinsight 使用pip的安装时间很长，且中间可能会出现卡死的情况，请耐心等待安装完成\n7.2 使用源码安装 参考官方教程从源码编译并安装Mindinsight\n7.3 验证安装结果 使用如下命令验证Mindinsight的安装结果\nmindinsight start 8. 运行Llama2 Mindformers自带Llama2的模型，可以直接使用API调用Llama2，在缺失权重文件和Token文件时会自动下载对应的缺失文件\n8.1 API接口调用 配置单机多卡或多机多卡需要额外的配置服务器的信息，这里先使用单机单卡推理任务验证环境是否配置成功，在任意文件夹创建如下Python文件，并命名为llama2.py\n可以根据如下几种API调用方法中的任意一种进行单机单卡推理任务，然后使用python llama2.py命令运行，使用API的接口调用Llama2需要提前使用pip安装Mindformers\nA. 基于AutoClass # llama2.py import mindspore from mindformers import AutoConfig, AutoModel, AutoTokenizer # 指定图模式，指定使用训练卡id mindspore.set_context(mode=0, device_id=0) tokenizer = AutoTokenizer.from_pretrained('llama2_7b') # model的实例化有以下两种方式，选择其中一种进行实例化即可 # 1. 直接根据默认配置实例化 model = AutoModel.from_pretrained('llama2_7b') # 2. 自定义修改配置后实例化 config = AutoConfig.from_pretrained('llama2_7b') config.use_past = True # 此处修改默认配置，开启增量推理能够加速推理性能 # config.xxx = xxx # 根据需求自定义修改其余模型配置 model = AutoModel.from_config(config) # 从自定义配置项中实例化模型 inputs = tokenizer(\u0026quot;I love Beijing, because\u0026quot;)[\u0026quot;input_ids\u0026quot;] # 首次调用model.generate()进行推理将包含图编译时间，推理性能显示不准确，多次重复调用以获取准确的推理性能 outputs = model.generate(inputs, max_new_tokens=30, do_sample=False) response = tokenizer.decode(outputs) print(response) # ['\u0026lt;s\u0026gt;I love Beijing, because it’s a city that is constantly changing. I have been living here for 10 years and I have seen the city change so much.I'] B. 基于Pipeline # llama2.py import mindspore from mindformers.pipeline import pipeline # 指定图模式，指定使用训练卡id mindspore.set_context(mode=0, device_id=0) pipeline_task = pipeline(\u0026quot;text_generation\u0026quot;, model='llama2_7b', max_length=30) pipeline_result = pipeline_task(\u0026quot;I love Beijing, because\u0026quot;, do_sample=False) print(pipeline_result) # [{'text_generation_text': ['\u0026lt;s\u0026gt;I love Beijing, because it’s a a city that is constantly changing. I have been living here for 10 years and I have']}] 8.2 Mindspore推理 使用API的方式调用Llama2推理性能较差，单机单卡在7B模型上大概只有1.3tokens/s的生成速度，通过下载Mindformers源码，并从源码编译运行Llama2模型将获得更快的推理速度，推理速度大概在10tokens/s左右。\n无论是基于Generate还是基于Pipeline的推理，文件的前半部分都是按照如下内容编写：\nimport mindspore as ms import numpy as np import os from mindspore import load_checkpoint, load_param_into_net from mindspore.train import Model from mindformers import MindFormerConfig, LlamaConfig, TransformerOpParallelConfig, AutoTokenizer, LlamaForCausalLM, pipeline from mindformers import init_context, ContextConfig, ParallelContextConfig from mindformers.tools.utils import str2bool, get_real_rank from mindformers.trainer.utils import get_last_checkpoint # 初始化输入内容 inputs = [ \u0026quot;I love Beijing, because\u0026quot;, \u0026quot;LLaMA is a\u0026quot;, \u0026quot;Huawei is a company that\u0026quot;, ] yaml_file=\u0026quot;/path/to/yaml_file.yaml\u0026quot; use_past = False seq_length = 512 checkpoint_path = \u0026quot;/path/ro/checkpoint.ckpt\u0026quot; model_type = \u0026quot;llama2_7b\u0026quot; # 读取配置文件 config = MindFormerConfig(yaml_file) print(config) # 初始化环境 tokenizer = AutoTokenizer.from_pretrained(model_type) init_context(use_parallel=config.use_parallel, context_config=config.context, parallel_config=config.parallel) model_config = LlamaConfig(**config.model.model_config) model_config.parallel_config = TransformerOpParallelConfig(**config.parallel_config) model_config.use_past = use_past model_config.seq_length = seq_length # 加载CheckPoint文件 if checkpoint_path and not config.use_parallel: model_config.checkpoint_name_or_path = checkpoint_path print(f\u0026quot;config is: {model_config}\u0026quot;) # 构建模型 model = LlamaForCausalLM(model_config) model.set_train(False) # 并行运行 if config.use_parallel: ckpt_path = os.path.join(checkpoint_path, \u0026quot;rank_{}\u0026quot;.format(get_real_rank())) ckpt_path = get_last_checkpoint(ckpt_path) print(\u0026quot;ckpt path: %s\u0026quot;, str(ckpt_path)) warm_up_model = Model(model) warm_up_model.infer_predict_layout(ms.Tensor(np.ones(shape=(1, model_config.seq_length)), ms.int32)) checkpoint_dict = load_checkpoint(ckpt_path) not_load_network_params = load_param_into_net(model, checkpoint_dict) print(\u0026quot;Network parameters are not loaded: %s\u0026quot;, str(not_load_network_params)) A. 基于Generate 新建llama2.py文件，将以上内容和以下内容合并为一个文件，并根据实际情况修改python文件中的变量参数，然后直接使用python脚本运行即可。\n# 导入上一小节的Python代码 ... # 获取输出 inputs_ids = tokenizer(inputs, max_length=model_config.seq_length, padding=\u0026quot;max_length\u0026quot;)[\u0026quot;input_ids\u0026quot;] outputs = model.generate(inputs_ids, max_length=model_config.max_decode_length, do_sample=model_config.do_sample, top_k=model_config.top_k, top_p=model_config.top_p) for output in outputs: print(tokenizer.decode(output)) B. 基于Pipeline 基于Pipeline的推理调用方法，用法与上一节相似，也需要将公共部分的代码复制到该文件的前半部分。\n# 导入上一小节的Python代码 ... # 获取输出 text_generation_pipeline = pipeline(task=\u0026quot;text_generation\u0026quot;, model=model, tokenizer=tokenizer) outputs = text_generation_pipeline(inputs, max_length=model_config.max_decode_length, do_sample=model_config.do_sample, top_k=model_config.top_k, top_p=model_config.top_p) for output in outputs: print(output) 8.3 性能分析 xxx\n附录 一、docker启动命令： isula run -it --ipc=host --name zhangdx \\ --device=/dev/davinci0 \\ --device=/dev/davinci1 \\ --device=/dev/davinci2 \\ --device=/dev/davinci3 \\ --device=/dev/davinci4 \\ --device=/dev/davinci5 \\ --device=/dev/davinci6 \\ --device=/dev/davinci7 \\ --device=/dev/davinci_manager \\ --device=/dev/devmm_svm \\ --device=/dev/hisi_hdc \\ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \\ -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ \\ -v /usr/local/sbin/:/usr/local/sbin/ \\ -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \\ -v /var/log/npu/conf/slog/slog.conf:/var/log/npu/conf/slog/slog.conf \\ -v /var/log/npu/slog/:/var/log/npu/slog \\ -v /var/log/npu/profiling/:/var/log/npu/profiling \\ -v /var/log/npu/dump/:/var/log/npu/dump \\ -v /var/log/npu/:/usr/slog \\ -v /home/zhangdx/:/root/ \\ --net=host \\ 9a2bf88cad61 \\ /bin/bash 二、配置容器内的虚拟器apt源： wget -O /etc/apt/sources.list https://repo.huaweicloud.com/repository/conf/Ubuntu-Ports-bionic.list apt-get update ","permalink":"https://www.zzudongxiang.com/posts/llama2-deployment/","summary":"\u003cdiv\u003e\n\u003ch2 id=\"1-创建docker\"\u003e1. 创建docker\u003c/h2\u003e\n\u003ch3 id=\"11-docker命令\"\u003e1.1 docker命令\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e显示全部的镜像：\u003ccode\u003edocker images\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e创建一个容器：\u003ccode\u003edocker run ...\u003c/code\u003e\u0026lt;查看1.2节内容\u0026gt;\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e显示全部的容器：\u003ccode\u003edocker ps -a\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e启动一个容器：\u003ccode\u003edocker start \u0026lt;id\u0026gt;\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e停止一个容器：\u003ccode\u003edocker stop \u0026lt;id\u0026gt;\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e进入一个正在运行的程序：\u003ccode\u003edocker exec -it \u0026lt;id\u0026gt; /bin/bash\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e删除一个容器：\u003ccode\u003edocker rm \u0026lt;id\u0026gt;\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"12-创建容器\"\u003e1.2 创建容器\u003c/h3\u003e\n\u003cp\u003e创建一个docker容器的时候需要同时挂载本地工作目录和相关的程序驱动，因此创建docker容器的命令参数较多，以下为一个创建docker容器命令的基本格式：\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e docker run -it --ipc=host --name \u0026lt;name\u0026gt; -v \u0026lt;local_path\u0026gt;:\u0026lt;docker_path\u0026gt;  \\\n     --workdir=\u0026lt;docker_path\u0026gt; \\\n     --pids-limit 409600 \\\n     --privileged --network=host \\\n     --shm-size=128G \\\n     --device=/dev/davinci0 \\\n     --device=/dev/davinci1 \\\n     --device=/dev/davinci2 \\\n     --device=/dev/davinci3 \\\n     --device=/dev/davinci4 \\\n     --device=/dev/davinci5 \\\n     --device=/dev/davinci6 \\\n     --device=/dev/davinci7 \\\n     --device=/dev/davinci_manager \\\n     --device=/dev/devmm_svm \\\n     --device=/dev/hisi_hdc \\\n     -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \\\n     -v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \\\n     -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ \\\n     -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \\\n     -v /usr/local/dcmi:/usr/local/dcmi \\\n     -v /etc/ascend_install.info:/etc/ascend_install.info \\\n     -v /etc/bashrc:/etc/bashrc \\\n     -p 223:223 \\\n     -p 224:6006 \\\n     -p 225:8080 \\\n     -p 226:8888 \\    \n     -u root \\\n     \u0026lt;image_id\u0026gt; /bin/bash\n\u003c/code\u003e\u003c/pre\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003e-it\u003c/code\u003e：已交互方式运行容器，并分配一个终端\u003c/p\u003e","title":"Llama2部署记录"},{"content":" 参考文献：\nNarayanan D, Shoeybi M, Casper J, et al. Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM: SC\u0026rsquo; 21, November 14-19, 2021, St. Louis, MO, USA\n\\[C\\], 2021. ACM, 2021-01-01.\n单一的MP或DP无法硬度继续增长的大模型算力需求，面对成千上万的GPU集群规模增长，结合TP、PP、DP等多种方式组成3D Parallelism的并行方式逐渐成为了主流的并行计算框架。\n1. 基于Megatron-LM 1.1 研究背景 单一的DP、TP、PP方法无法满足日益增长的模型参数量，因此提出一种基于多种并行方法的PTD-P并行技术。 1.2 实现方法 图. 默认的Pipeline调度（上）和插值的Pipeline调度（下）\n对每个设备上运行的网络层进行进一步拆分，每个子集称为一个Chunk，在图（下）中用深色和浅色两种颜色表示\n假设一共4个Device，每个Device可以分为4层（例如：在Device 1上运行1~4层，Device 2上运行5-8），则可以将每个设备的计算过程分为两个Chunk（每个Chunk需要计算两层网络）例如：Device 1对应1，2，9，10四层，Device 2对应3，4，11，12四层。\n以Device 3为例，为什么运行完Chunk 2的Batch2后需要Wait，而不是直接运行Batch 3？只是为了展示插值的概念？\n1.3 实验结论 提出一种插值Pipeline调度算法，实现在3072个GPU上训练1T参数的训练，总体算力达到502PFLOPS，单个GPU的算力达到了理论峰值的52%。\n相比较ZeRO-3（不带MP），因为减少了通信量，在175B和530B规模的大模型上效果要好70%\n插值Pipeline调度算法可以增加计算密集度，但是对通信的开销也会增加\nPP在较大的模型上效率更高，效果更好，TP的并行方式会增加不同设备之间的通信量\n重算技术只是一个为了平衡内存与算力之间可选的技术，会降低内存消耗，但同时也会增加1/3的算力消耗\n高度的MP可能会导致较小的矩阵乘运算，降低GPU的利用率\n1.4 实验数据 本文对PTD-P模型中，GPU数量、全局Batch Size、Microbatch Size、Bubble Time、Throughput等多个参量进行多角度多变量讨论\n本文还对Checkpoint的加载和保存提出讨论\n","permalink":"https://www.zzudongxiang.com/posts/3d-parallelism/","summary":"\u003cdiv\u003e\n\u003cblockquote\u003e\n\u003cp\u003e参考文献：\u003c/p\u003e\n\u003cp\u003e\u003cspan style=\"font-size: 14.4px\"\u003eNarayanan D, Shoeybi M, Casper J, et al. Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM: SC\u0026rsquo; 21, November 14-19, 2021, St. Louis, MO, USA\u003c/p\u003e\n\\[C\\]\u003cp\u003e, 2021. ACM, 2021-01-01.\u003c/span\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e单一的MP或DP无法硬度继续增长的大模型算力需求，面对成千上万的GPU集群规模增长，结合TP、PP、DP等多种方式组成3D Parallelism的并行方式逐渐成为了主流的并行计算框架。\u003c/p\u003e\n\u003ch2 id=\"1-基于megatron-lm\"\u003e1. 基于Megatron-LM\u003c/h2\u003e\n\u003ch3 id=\"11-研究背景\"\u003e1.1 研究背景\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e单一的DP、TP、PP方法无法满足日益增长的模型参数量，因此提出一种基于多种并行方法的PTD-P并行技术。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"12-实现方法\"\u003e1.2 实现方法\u003c/h3\u003e\n\u003cimg src=\"images/image-usvb.png\" style=\"display: inline-block;width:80.0%\" /\u003e\n\u003cp\u003e图. 默认的Pipeline调度（上）和插值的Pipeline调度（下）\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e对每个设备上运行的网络层进行进一步拆分，每个子集称为一个Chunk，在图（下）中用深色和浅色两种颜色表示\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e假设一共4个Device，每个Device可以分为4层（例如：在Device 1上运行1~4层，Device 2上运行5-8），则可以将每个设备的计算过程分为两个Chunk（每个Chunk需要计算两层网络）例如：Device 1对应1，2，9，10四层，Device 2对应3，4，11，12四层。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e以Device 3为例，为什么运行完Chunk 2的Batch2后需要Wait，而不是直接运行Batch 3？只是为了展示插值的概念？\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"13-实验结论\"\u003e1.3 实验结论\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e提出一种插值Pipeline调度算法，实现在3072个GPU上训练1T参数的训练，总体算力达到502PFLOPS，单个GPU的算力达到了理论峰值的52%。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e相比较ZeRO-3（不带MP），因为减少了通信量，在175B和530B规模的大模型上效果要好70%\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e插值Pipeline调度算法可以增加计算密集度，但是对通信的开销也会增加\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ePP在较大的模型上效率更高，效果更好，TP的并行方式会增加不同设备之间的通信量\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e重算技术只是一个为了平衡内存与算力之间可选的技术，会降低内存消耗，但同时也会增加1/3的算力消耗\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e高度的MP可能会导致较小的矩阵乘运算，降低GPU的利用率\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"14-实验数据\"\u003e1.4 实验数据\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e本文对PTD-P模型中，GPU数量、全局Batch Size、Microbatch Size、Bubble Time、Throughput等多个参量进行多角度多变量讨论\u003c/p\u003e","title":"3D并行（3D Parallelism）"},{"content":" 1. Nvidia GPU 参考文献：\nHeKun-NVIDIA. CUDA-Programming-Guide-in-Chinese\n\\[EB/OL\\]. https://github.com/HeKun-NVIDIA/CUDA-Programming-Guide-in-Chinese.\nNvidia. Nvidia CUDA编程指南\n\\[M\\]. 1.1. Nvidia, 2008.\n1.1 GPU架构 软件层面架构：Nvidia GPU的架构在进行CUDA软件操作时可以抽象为：Thread-\u0026gt;Block-\u0026gt;Grid三层，通过指定这三个参数可以精确的控制目标运算放在目标的Thread上进行计算。\n硬件层面架构：在硬件层可以讲GPU抽象为：SP(Streaming Processor)-\u0026gt;SM(Streaming Multiprocessor)-\u0026gt;Device三层，基本对应CUDA软件编程层面的Thread-\u0026gt;Block-\u0026gt;Grid，Nvidia的GPU在指令集上属于是SIMD（Single Instruction Multiple Data）架构，可以实现单条指令在多个数据的并行处理。\n集群层面架构：在集群层面，一般按照Host-Device结构划分，其中一个Host可以视作一个由CPU、GPU、内存、硬盘等组成的主机，Device一般特指某一个指定的GPU设备，也就是软件层面的Grid。\n图. Nvidia的GPU架构\nA. SP / Thread GPU上每个SP主要由ALU（逻辑控制单元）与FPU（浮点运算单元）组成，可以进行简单的逻辑运算与浮点运算，每个SP在对应软件层面可以操作的一个Thread，也是开发者可以操作的最小单元，用户可以借助CUDA在Thread上实现SPMD（Single Program Multiple Data）操作。\nB. MP / Block 多个Thread组成一个Block，同一个Block上的Thread共享同一块内存（Shared Memory），这种方法可以实现同一个Block上并行的Thread可以并行的对同一块内存中的数据进行操作。\n在进行CUDA编程时，开发者可以借助一个SM控制多个Block中的Thread进行运算，SM中还包含一些必要的寄存器、共享内存、L1Cache、Scheduler、SPU、LD/ST单元等。\nC. Device / Grid 多个Block一起共同组成一个Grid，也就是硬件层面与集群层面的Device，借助该概念可以实现集群中多个GPU之间的数据传输和并行计算。\n1.2 GPU编程 Nvidia的GPU上有多个Thread可以并行的完成矩阵运算，例如在进行通用矩阵乘（GEMM，General matrix multiply）时，不同Thread在共享内存中取出对应位置的数据进行计算，并讲结果重新放置在共享内存中以实现GEMM的并行计算。\n图. 使用共享内存并行计算矩阵乘\n在代码层面的实现过程大致如下：\n// Host层面的矩阵乘，假定矩阵的维度是BLOCK_SIZE的整数倍 void MatMul(const Matrix A, const Matrix B, Matrix C) { // 从显存中加载A和B两个矩阵的数据 cudaMalloc(..., size); cudaMemcpy(..., ..., size, cudaMemcpyHostToDevice); // 从设备显存中申请储存乘法运算结果的矩阵C cudaMalloc(\u0026amp;d_C.elements, size); // 调用内核 MatMulKernel\u0026lt;\u0026lt;\u0026lt;dimGrid, dimBlock\u0026gt;\u0026gt;\u0026gt;(d_A, d_B, d_C); // \u0026lt;\u0026lt;\u0026lt;dimGrid, dimBlock\u0026gt;\u0026gt;\u0026gt; // 从显存中获取计算结果C cudaMemcpy(..., ..., size, cudaMemcpyDeviceToHost); // 释放显存 cudaFree(...); } // 调用MatMul()以实现Kernel层的矩阵乘 __global__ void MatMulKernel(Matrix A, Matrix B, Matrix C) { // __global__ // 每个Thread计算矩阵C中的一个元素，并将结果累加到CValue中 float Cvalue = 0; int row = blockIdx.y * blockDim.y + threadIdx.y; int col = blockIdx.x * blockDim.x + threadIdx.x; for (int e = 0; e \u0026lt; A.width; ++e) Cvalue += A.elements[row * A.width + e] * B.elements[e * B.width + col]; C.elements[row * C.width + col] = Cvalue; } 2. Huawei NPU Huawei的NPU设备Ascend 910B相较于Nvidia的GPU做了一些有针对性的优化，同时由于NPU主要针对神经网络训练与推理，因此其在芯片设计架构上与Nvidia的GPU拥有完全不同的设计思路。\n2.1 NPU架构 Ascend的芯片架构名称为DaVinci，DaVinci主要针对神经网络的训练和推理进行优化，它的应用场景与GPGPU（General-Purpose Graphics Processing Unit）不同3。其中Ascend中的AI Core中的处理架构图#所示，它包含标量计算单元、向量计算单元、矩阵计算单元、本地数据存储单元Local Memory，以及负责数据搬运的DMA单元等4。\n图. DaVinci的AI Core架构\n不同版本的Ascend对应的算力资源和应用场景有所不同，通常情况下可以分为以下5个版本的Ascend芯片，其对应的应用场景和常用的算法或网络如表#所示：\n表. Ascend分类以及其典型应用\nA. TS 为了能够实现计算任务在AI Core上的高效分配和调度，该处理器还特意配备了一个专用CPU作为任务调度器（Task Scheduler，TS），Ascend定制一个CPU负责任务调度，合理利用AI Core中的各个单元的并行任务。\nB. MTE 在AI Core中，输入缓冲区之后设置了一个存储转换单元（Memory Transfer Engine，MTE）。这是达芬奇架构的特色之一，主要的目的是为了以极高的效率实现数据格式的转换。Ascend相较于Nvidia的通用GPU其特点就是内存处理上，GPU上通常每次运算需要从DDR上获取数据，但Ascend可以将热数据放在定制的缓存区中，以加快运算效率。\nMTE的核心是双Buffer机制，在运算的过程中是应用DMA搬运数据到指定的内存或缓存中。\nC. 矩阵计算单元 达芬奇架构在AI Core中特意设计了矩阵计算单元作为昇腾AI处理器的核心计 算模块，意图高效解决矩阵计算的瓶颈问题。\nAscend内置一个16x16的矩阵运算模块，针对16x16矩阵的乘加运算进行硬件优化。\n当待运算的矩阵大小超过16x16时，需要将矩阵按照16x16大小进行拆分运算，并通过多次矩阵运算求得最终运算结果。\nD. 数据通路 达芬奇架构数据通路的特点是多进单出，数据流入AI Core可以通过多条数据通路，可以从外部直接流入矩阵计算单元、输入缓冲区和输出缓冲区中的任何一个，流入路径的方式比较灵活，在软件的控制下由不同数据流水线分别进行管理。而数据输出则必须通过输出缓冲区，最终才能输出到核外存储系统中。\nAscend为了AI计算差异性定制NPU的内部组成结构。\n从计算体系结构到储存结构、数据流向、流程控制等完全不同，在一定程度上不具有可比性。\nE. 资源利用率 对于昇腾AI处理器来说，合理设计数据 存储和传输结构对于系统的最终运行性能至关重要。不合理的设计往往成为系统性能瓶颈,从而白白浪费片上海量的计算资源。\nGPU、NPU、TPU等AI计算芯片的核心发展方向为合理利用全部的片上资源（计算资源、储存资源等）以提高算力和能耗比\n2.2 NPU编程 Ascend C编程范式是一种流水线式的编程范式，把算子核内的处理程序，分成多个流水任务，通过队列（Queue）完成任务间通信和同步，并通过统一的内存管理模块（Pipe）管理任务间通信内存。流水编程范式应用了流水线并行计算方法6。\n图. Ascend编程流水线方式\nAscend编程的核心思路为将神经网络计算过程中的矩阵计算、向量计算、标量计算等拆分成多个子模块，并使用硬件计算模块对计算过程进行加速，同时配合MTE和TS模块实现边计算边传输，提高计算效率。\n","permalink":"https://www.zzudongxiang.com/posts/nvidia-gpu-huawei-npu/","summary":"\u003cdiv\u003e\n\u003ch1 id=\"1-nvidia-gpu\"\u003e1. Nvidia GPU\u003c/h1\u003e\n\u003cblockquote\u003e\n\u003cp\u003e参考文献：\u003c/p\u003e\n\u003cp\u003e\u003cspan style=\"font-size: 14.4px\"\u003eHeKun-NVIDIA. CUDA-Programming-Guide-in-Chinese\u003c/p\u003e\n\\[EB/OL\\]\u003cp\u003e. \u003c/span\u003e\u003ca href=\"https://github.com/HeKun-NVIDIA/CUDA-Programming-Guide-in-Chinese\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"\u003e\u003cspan style=\"font-size: 14.4px\"\u003e\u003ca href=\"https://github.com/HeKun-NVIDIA/CUDA-Programming-Guide-in-Chinese\"\u003ehttps://github.com/HeKun-NVIDIA/CUDA-Programming-Guide-in-Chinese\u003c/a\u003e\u003c/span\u003e\u003c/a\u003e\u003cspan style=\"font-size: 14.4px\"\u003e.\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003eNvidia. Nvidia CUDA编程指南\u003c/p\u003e\n\\[M\\]\u003cp\u003e. 1.1. Nvidia, 2008.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"11-gpu架构\"\u003e1.1 GPU架构\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e软件层面架构\u003c/strong\u003e：Nvidia GPU的架构在进行CUDA软件操作时可以抽象为：\u003ccode\u003eThread-\u0026gt;Block-\u0026gt;Grid\u003c/code\u003e三层，通过指定这三个参数可以精确的控制目标运算放在目标的\u003ccode\u003eThread\u003c/code\u003e上进行计算。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e硬件层面架构\u003c/strong\u003e：在硬件层可以讲GPU抽象为：\u003ccode\u003eSP(Streaming Processor)-\u0026gt;SM(Streaming Multiprocessor)-\u0026gt;Device\u003c/code\u003e三层，基本对应CUDA软件编程层面的\u003ccode\u003eThread-\u0026gt;Block-\u0026gt;Grid\u003c/code\u003e，Nvidia的GPU在指令集上属于是SIMD（Single Instruction Multiple Data）架构，可以实现单条指令在多个数据的并行处理。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e集群层面架构\u003c/strong\u003e：在集群层面，一般按照\u003ccode\u003eHost-Device\u003c/code\u003e结构划分，其中一个\u003ccode\u003eHost\u003c/code\u003e可以视作一个由CPU、GPU、内存、硬盘等组成的主机，\u003ccode\u003eDevice\u003c/code\u003e一般特指某一个指定的GPU设备，也就是软件层面的\u003ccode\u003eGrid\u003c/code\u003e。\u003c/p\u003e\n\u003cimg src=\"images/image-exzl.png\" style=\"display: inline-block;width:65.0%\" /\u003e\n\u003cp\u003e图. Nvidia的GPU架构\u003c/p\u003e\n\u003ch3 id=\"a-sp--thread\"\u003eA. SP / Thread\u003c/h3\u003e\n\u003cp\u003eGPU上每个\u003ccode\u003eSP\u003c/code\u003e主要由ALU（逻辑控制单元）与FPU（浮点运算单元）组成，可以进行简单的逻辑运算与浮点运算，每个\u003ccode\u003eSP\u003c/code\u003e在对应软件层面可以操作的一个\u003ccode\u003eThread\u003c/code\u003e，也是开发者可以操作的最小单元，用户可以借助CUDA在\u003ccode\u003eThread\u003c/code\u003e上实现SPMD（Single Program Multiple Data）操作。\u003c/p\u003e\n\u003ch3 id=\"b-mp--block\"\u003eB. MP / Block\u003c/h3\u003e\n\u003cp\u003e多个\u003ccode\u003eThread\u003c/code\u003e组成一个\u003ccode\u003eBlock\u003c/code\u003e，同一个\u003ccode\u003eBlock\u003c/code\u003e上的\u003ccode\u003eThread\u003c/code\u003e共享同一块内存（Shared Memory），这种方法可以实现同一个\u003ccode\u003eBlock\u003c/code\u003e上并行的\u003ccode\u003eThread\u003c/code\u003e可以并行的对同一块内存中的数据进行操作。\u003c/p\u003e\n\u003cp\u003e在进行CUDA编程时，开发者可以借助一个\u003ccode\u003eSM\u003c/code\u003e控制多个\u003ccode\u003eBlock\u003c/code\u003e中的\u003ccode\u003eThread\u003c/code\u003e进行运算，\u003ccode\u003eSM\u003c/code\u003e中还包含一些必要的寄存器、共享内存、L1Cache、Scheduler、SPU、LD/ST单元等。\u003c/p\u003e\n\u003ch3 id=\"c-device--grid\"\u003eC. Device / Grid\u003c/h3\u003e\n\u003cp\u003e多个\u003ccode\u003eBlock\u003c/code\u003e一起共同组成一个\u003ccode\u003eGrid\u003c/code\u003e，也就是硬件层面与集群层面的\u003ccode\u003eDevice\u003c/code\u003e，借助该概念可以实现集群中多个GPU之间的数据传输和并行计算。\u003c/p\u003e\n\u003ch2 id=\"12-gpu编程\"\u003e1.2 GPU编程\u003c/h2\u003e\n\u003cp\u003eNvidia的GPU上有多个\u003ccode\u003eThread\u003c/code\u003e可以并行的完成矩阵运算，例如在进行通用矩阵乘（GEMM，General matrix multiply）时，不同\u003ccode\u003eThread\u003c/code\u003e在共享内存中取出对应位置的数据进行计算，并讲结果重新放置在共享内存中以实现GEMM的并行计算。\u003c/p\u003e\n\u003cimg src=\"images/image-putm.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003cp\u003e图. 使用共享内存并行计算矩阵乘\u003c/p\u003e\n\u003cp\u003e在代码层面的实现过程大致如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e \u003cspan style=\"color:#75715e\"\u003e// Host层面的矩阵乘，假定矩阵的维度是BLOCK_SIZE的整数倍\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e \u003cspan style=\"color:#66d9ef\"\u003evoid\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eMatMul\u003c/span\u003e(\u003cspan style=\"color:#66d9ef\"\u003econst\u003c/span\u003e Matrix A, \u003cspan style=\"color:#66d9ef\"\u003econst\u003c/span\u003e Matrix B, Matrix C) {\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#75715e\"\u003e// 从显存中加载A和B两个矩阵的数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#a6e22e\"\u003ecudaMalloc\u003c/span\u003e(..., size);\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#a6e22e\"\u003ecudaMemcpy\u003c/span\u003e(..., ..., size, cudaMemcpyHostToDevice);\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#75715e\"\u003e// 从设备显存中申请储存乘法运算结果的矩阵C\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#a6e22e\"\u003ecudaMalloc\u003c/span\u003e(\u003cspan style=\"color:#f92672\"\u003e\u0026amp;\u003c/span\u003ed_C.elements, size);\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#75715e\"\u003e// 调用内核\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     MatMulKernel\u003cspan style=\"color:#f92672\"\u003e\u0026lt;\u0026lt;\u0026lt;\u003c/span\u003edimGrid, dimBlock\u003cspan style=\"color:#f92672\"\u003e\u0026gt;\u0026gt;\u0026gt;\u003c/span\u003e(d_A, d_B, d_C); \u003cspan style=\"color:#75715e\"\u003e// \u0026lt;\u0026lt;\u0026lt;dimGrid, dimBlock\u0026gt;\u0026gt;\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#75715e\"\u003e// 从显存中获取计算结果C\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#a6e22e\"\u003ecudaMemcpy\u003c/span\u003e(..., ..., size, cudaMemcpyDeviceToHost); \n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#75715e\"\u003e// 释放显存\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#a6e22e\"\u003ecudaFree\u003c/span\u003e(...);\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e }\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e \u003cspan style=\"color:#75715e\"\u003e// 调用MatMul()以实现Kernel层的矩阵乘\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e __global__ \u003cspan style=\"color:#66d9ef\"\u003evoid\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eMatMulKernel\u003c/span\u003e(Matrix A, Matrix B, Matrix C) { \u003cspan style=\"color:#75715e\"\u003e// __global__\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#75715e\"\u003e// 每个Thread计算矩阵C中的一个元素，并将结果累加到CValue中\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#66d9ef\"\u003efloat\u003c/span\u003e Cvalue \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#ae81ff\"\u003e0\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#66d9ef\"\u003eint\u003c/span\u003e row \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e blockIdx.y \u003cspan style=\"color:#f92672\"\u003e*\u003c/span\u003e blockDim.y \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e threadIdx.y;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#66d9ef\"\u003eint\u003c/span\u003e col \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e blockIdx.x \u003cspan style=\"color:#f92672\"\u003e*\u003c/span\u003e blockDim.x \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e threadIdx.x;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     \u003cspan style=\"color:#66d9ef\"\u003efor\u003c/span\u003e (\u003cspan style=\"color:#66d9ef\"\u003eint\u003c/span\u003e e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#ae81ff\"\u003e0\u003c/span\u003e; e \u003cspan style=\"color:#f92672\"\u003e\u0026lt;\u003c/span\u003e A.width; \u003cspan style=\"color:#f92672\"\u003e++\u003c/span\u003ee)\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e         Cvalue \u003cspan style=\"color:#f92672\"\u003e+=\u003c/span\u003e A.elements[row \u003cspan style=\"color:#f92672\"\u003e*\u003c/span\u003e A.width \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e e] \u003cspan style=\"color:#f92672\"\u003e*\u003c/span\u003e B.elements[e \u003cspan style=\"color:#f92672\"\u003e*\u003c/span\u003e B.width \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e col];\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e     C.elements[row \u003cspan style=\"color:#f92672\"\u003e*\u003c/span\u003e C.width \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e col] \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e Cvalue;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e }\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"2-huawei-npu\"\u003e2. Huawei NPU\u003c/h1\u003e\n\u003cp\u003eHuawei的NPU设备Ascend 910B相较于Nvidia的GPU做了一些有针对性的优化，同时由于NPU主要针对神经网络训练与推理，因此其在芯片设计架构上与Nvidia的GPU拥有完全不同的设计思路。\u003c/p\u003e","title":"Nvidia GPU与Huawei NPU"},{"content":" 参考文献：\nHuang Y, Cheng Y, Chen D, et al. GPipe: Efficient Training of Giant Neural Networks using Pipeline Parallelism: 33rd Conference on Neural Information Processing Systems (NeurIPS 2019),\n\\[C\\], Vancouver, Canada, 2018.\nHarlap A, Narayanan D, Phanishayee A, et al. PipeDream: Fast and Efficient Pipeline Parallel DNN Training\n\\[J\\]. ArXiv, 2018,abs/1806.03377.\nKim T, Kim H, Yu G, et al. BPipe: Memory-Balanced Pipeline Parallelism for Training Large Language Models: Proceedings of the 40th International Conference on Machine Learning\n\\[C\\], Proceedings of Machine Learning Research, 2023. PMLR.\n流水线并行（Pipeline Parallelism，PP）属于模型并行（MP）中的一种，它的核心思想是将模型进行横向分割（假定模型为由下向上的传递方式）。\n1. GPipe 神经网络在设计的时候一般按照层或者模块组合构成的，因此可以自然而然的将神经网络按照其自身的网络层分割，平均的将每一层放置到不同的设备上运行以实现并行计算的架构。\n1.1 研究背景 由于神经网络是在设计之初就是按照层尽心分割的，每一层都有指定格式的输入和输出，并在层内部进行运算，因此可以按照神经网络的层将一个完整的网络拆分到多个设备上并行的进行计算。 1.2 实现方法 图. GPipe的工作流程\n如图（a）所示，假设神经网络一共有4层，并可以均匀的分配到4个设备上，其中前向传播用F_0到F_3表示，后向传播用B_0到B_3表示\n如图（b）所示，Device 0完成F_0后Device 1开始进行F_1操作，后向传播时同样需要依赖上一级完成操作后并将参数传递给指定设备，这种方式只是降低了GPU的算力，同一时间只有一个GPU参与运算，并没有实现并行计算\n如图（c）所示，将一个Batch分为4个Microbatch，并依次送入流水线中进行计算，如图所示，在第1个时刻只有一个GPU参与运算，在第2个时刻有两个GPU并行参与计算，第4个时刻4个GPU同时参与运算，但是即便将一个Batch分为4个Microbatch，依旧会存在Bubble时间，该时间会导致集群的计算效率下降\n假设PP的并行数量为K，Microbatch的数量为M，每个Microbatch的大小为N，模型的层数为L\n当M \u0026gt; 4 x K时可以忽略Bubble时间\n由于在前向传播计算式需要保留大量的中间变量以便于后续的后向传播计算，通过Recompute机制之后可以在前向传播之后抛弃计算的中间值，在后向传播计算时，再重新计算一次\n1.3 实验结论 通过Microbatch和Recompute机制可以实现降低Bubble时间并降低内存消耗\nPP的前提是需要假定可以将神经网络均匀的分割到每一个设备上，确保每个设备上的算力消耗是均等的，否则算力较小的设备容易成为短板影响集群的整体性能\n后向传播对算力的消耗大约是前向传播对算力消耗的2倍，通过合计的设置Microbatch大小和Recompute机制，可以将Bubble的开销降低到4.1%\n如果模型中存在Batch Normalization操作，则需要等待并同步所有节点的运算结果才可以继续进行\n1.4 实验数据 1.4.1 耗时占比测试 图. 训练过程中每个阶段的耗时占比\n有效的计算时间占比超过88%（后向传播占比65.6%，重算占比22.5%）\n是不是意味着如果没有重算机制，GPipe的方法实际计算效率并不是很高（65.6%） 由于网络分割出的各个子序列算力不平衡导致的时间占比约3.2%，如果分割的进一步不平衡，则该比例数值可能会进一步增大\n1.4.2 内存开销测试 表. 不同模型下并行数量和内存开销的关系\n根据正文的相关描述，第一行的NVIDIA GPU应该是Cloud TPU v2\n假设只有单卡（Naive-1）的情况下，可以运行82M参数量的AmoebaNet模型，但是如果引入重算机制，在Pipelin-1的条件下，可运行的参数量提升到318M\n在TPU v3情况下，Naive-1可运行282.2M的模型，引入重算机制后Pipeline-1可运行785.8M的模型，但是理论上模型的参数量和总的模型参数占用内存应该呈正相关，但是这里总占用内存量却下降了\n对于AmoebaNet网络，分割时为了保证每个Pipeline的算力差不多相同，但实际内存占用量缺有差异，从而整体性能可能会收到一定的影响\n2. PipeDream 2.1 研究背景 基于Microbatch的GPipe仍然会存在一定的Bubble时间导致总体效率下降，通过重新设计Pipeline的调度算法，实现1F1B的Pipeline调度算法，提高PP的效率。 2.2 实现方法 图. 4台设备下的PipeDream方法示意图\nGPipe的思想是算完全部Microbatch的FWD后再开始BWD计算，通过增加Microbatch的大小的方法降低Bubble时间，但是Microbatch的尺寸过小可能会导致通信效率降低，从而影响整体性能\nPipeDream的优化方案是无需等待全部Microbatch的FWD算完，每算完一次Microbatch的FWD，就立刻开始计算其BWD，通过这种交叉进行的方式可以降低Bubble时间\n除了Startup State和最后的阶段，中间的Steady State几乎是没有Bubble时间消耗的\n在PP的基础上加上DP和MP方案实现3D并行\n2.3 实验结论 在DNN上，降低了DP条件下95%的通信开销，同时实现了通信与计算的异步进行\n相比较其他的方案，训练精度更好，训练效果更好\n相比较GPipe降低了Bubble时间，提高了GPU的算力\n2.4 实验数据 2.4.1 通信开销实验 图. 在不同设备，不同模型下的通信开销\n算力越高的设备通信开销的占比越大（算力：K80 \u0026lt; Titan X \u0026lt; V100）\n并行的机器数量越多，通信开销越大，适用于所有算力的设备与所有模型\n2.4.2 训练效率 图. 8个设备上的训练时间和训练精度变化\n在VGG16和Inception-v3两个模型上PipeDream都能更快的达到目标训练精度\n在VGG16上，达到目标精度所消耗的时间相比单机缩短了近70倍\n2.4.3 速度提升 图. VGG16下MP vs. PP vs. PipeDream速度提升\n在4个设备和8个设备的情况下，PipeDream的性能提升都是最好的\n这里的PipeDream是指在PP的优化的基础上结合DP和MP的方案\n3. BPipe 3.1 研究背景 BPipe优化的方向是认为Pipeline方式靠前的Stage（Device/Machine）由于需要储存更多的Activating Memory导致占用的内存更大，从而导致不同的Stage之间内存消耗不平衡。 3.2 实现方法 图. 4个Stage 8个Microbatch条件下的BPipe流程图\nStage 0在进行BWD 0之前需要储存FWD 0 ~ FWD3的Activation Memory，但是Stage 3在计算BWD 0之前只需要储存FWD 0的Activation Memory即可，且在计算完BWD 0后即可释放一部分的Activation空间\n在后续的计算过程中Stage 0需要储存至少4个FWD的Activation Memory，而Stage 3计算完成后即可释放对应的Activation Memory，因此其只需要储存最多1个FWD的Activation Memory\n类似PipeDream的插值Pipeline虽然可以极大的降低Bubble时间的，但是也会导致不同设备之间的内存消耗不一致\n图. Activation Memory平衡策略\n如图所示为BPipe的Activation Memory平衡机制，在只有4个Stage的情况下，Stage 0和Stage 1互联交换内存，实现内存平衡\n在Stage数量增多时，可以使用NVLink替代传统的Ethernet或InfiniBand网络，实现更高的数据传输带宽\n图. 传统使用Ethernet/InfiniBand链接的结构和使用NVLink连接的结构\n3.3 实验结论 BPipe的处理方法就是在不同的Stage之间传输内存消耗量，其实有点类似ZeRO的方法\n主要优化方法是把Stage0和Stage15（假设有16个Stage）使用高带宽的NVLink连接在一起进行内存共享与内存交换\n3.4 实验数据 3.4.1 内存使用量测试 图. PP中每个Stage的内存使用量（GPT-3 134B）\n使用BPipe之前Stage 0的内存使用量将会超过80GB，超出了单设备的内容总容量上限 ","permalink":"https://www.zzudongxiang.com/posts/pipeline-parallelism/","summary":"\u003cdiv\u003e\n\u003cblockquote\u003e\n\u003cp\u003e参考文献：\u003c/p\u003e\n\u003cp\u003eHuang Y, Cheng Y, Chen D, et al. GPipe: Efficient Training of Giant Neural Networks using Pipeline Parallelism: 33rd Conference on Neural Information Processing Systems (NeurIPS 2019),\u003c/p\u003e\n\\[C\\]\u003cp\u003e, Vancouver, Canada, 2018.\u003c/p\u003e\n\u003cp\u003e\u003cspan style=\"font-size: 14.4px\"\u003eHarlap A, Narayanan D, Phanishayee A, et al. PipeDream: Fast and Efficient Pipeline Parallel DNN Training\u003c/p\u003e\n\\[J\\]\u003cp\u003e. ArXiv, 2018,abs/1806.03377.\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan style=\"font-size: 14.4px\"\u003eKim T, Kim H, Yu G, et al. BPipe: Memory-Balanced Pipeline Parallelism for Training Large Language Models: Proceedings of the 40th International Conference on Machine Learning\u003c/p\u003e","title":"流水线并行（Pipeline Parallelism）"},{"content":" 参考文献：\nTeam D, Majumder R, President V, et al. DeepSpeed: Extreme-scale model training for everyone\n\\[J\\]. Microsoft, 2020.\nRajbhandari S, Rasley J, Ruwase O, et al. ZeRO: Memory optimizations Toward Training Trillion Parameter Models\n\\[C\\], 2020. IEEE, 2020-01-01.\nRen J, Rajbhandari S, Aminabadi R Y, et al. ZeRO-Offload: Democratizing Billion-Scale Model Training\n\\[J\\]. arXiv.org, 2021.\nRajbhandari S, Ruwase O, Rasley J, et al. ZeRO-Infinity: Breaking the GPU MemoryWall for Extreme Scale Deep Learning: SC\u0026rsquo; 21, November 14–19, 2021, St. Louis, MO, USA\n\\[C\\], 2021.\n在传统的数据并行（Data Parallelism，DP）过程中，每个节点的都需要保存一份完成的网络模型和对应的参数，这导致了大量的冗余内存占用。当训练的大模型参数足够大时，并行计算节点的内存容量将无法支持一个模型的训练量，这大大的限制了大模型的发展。在并行计算时，为了降低单一节点的内存占用量，可以采用模型并行（Model Parallelism，MP），但MP的方式将会增加大模型网络的搭建工作量。\n1. ZeRO ZeRO是Microsoft提出的一种零冗余优化（Zero Redundancy Optimizer，ZeRO）概念，通过ZeRO技术可以实现大规模的数据并行，且增加的额外网络通信带宽要求是可接受的。\n1.1 研究背景 数据并行占用过多内存导致单节点单设备无法容纳完整的大模型网络，从而限制大模型训练的发展。 1.2 实现方法 图. 每个GPU上模型消耗的内存使用情况\n通过分析发现，数据并行时GPU在某一时间内只会使用到指定网络对应的内存空间，而其他空间的内存可视为无效占用，可以考虑将这些暂时未用到的内存放置在其他位置（其他GPU中），在需要的时候通过网络通信传回使用，使用完成后再更新到其他指定位置；\n通过分析大模型训练对内存占用的类型，可以将内存占用分为两部分：Optimizing Model State Memory（ZeRO-DP）和Optimizing Residual State Memory（ZeRO-R）。\n通过对ZeRO-DP中的内存类型进行分析，又可以将ZeRO-DP内存的使用分为三部分：Optimizer State Partitioning（P_{os} / ZeRO-1）、Add Gradient Partitioning（P_{os+g} / ZeRO-2）、Add Parameter Partitioning（P_{os+g+p} / ZeRO-3）\n通过将ZeRO-DP的数据分布式存储到不同的GPU中可以实现大模型训练对内存容量的要求，如上图所示为ZeRO对每个GPU上的内存占用策略，其中K表示Optimizer States的乘数，\\Psi表示模型的参数量，N_d表示并行的设备数量。\nZeRO-R的数据可以使用Offload技术和Recompute技术降低内存开销\n训练过程中由于Pytorch自动申请和释放内存造成的内存碎片，采用预分配和内存管理的方法解决\n1.3 实验结论 ZeRO-1和ZeRO两个阶段由于在DP时需要必须的All-Reduce操作，因此不会增加额外的通信量\n每个Device储存的梯度参数和优化器参数与上下层之间相关，因此无论是否引入ZeRO机制，都需要进行网络通信进行All-Reduce操作 ZeRO-3会增加一部分的额外通信需求，但最多增加1.5x的通信吞吐量\n在引入ZeRO之前，每个Device都有一份完整的参数信息，但由于引入了ZeRO机制，当Device需要运算的模型参数不在当前设备上时，则需要从对应设备上获取，因此会增加一部分的通信量。 ZeRO机制理论上可以支持最大1T参数规模的模型训练，但是当模型参数规模达到100B时，或GPU的数量超过256个时，性能有明显的下降。\n1.4 实验数据 1.4.1 参数量级的测试 图. 在不同参数量级下的ZeRO的速度提升（对比模型：SOTA MP）\nZeRO的训练总是可以在一个节点内部完成，但是对于大于40B参数的模型SOTA MP必须跨节点才可以完成训练；\n当模型参数超过100B规模，则ZeRO的GPU吞吐量将会有所下降，主要原因可能是网络通信造成的瓶颈，同样也会对MP的GPU吞吐量造成影响，因此Speed up并没有明显的下降；\n1.4.2 GPU数量的测试 图. 不同GPU数量下使用ZeRO-100训练一个60B参数的模型的算力变化\nGPU数量与算力性能之间的超线性关系（绿线为实际性能变化，蓝线为线性增长的曲线，对应左侧坐标轴），由于使用ZeRO会降低单个Device的内存占用，导致运算过程中可以有更多的内存空间可以使用，使得芯片的算力也受影响的有一定层度的增加；\n随着GPU数量的增加，当GPU超过256个时，单个GPU的算力性能有所下降，预计也是受网络通信带宽的影响导致的算力下降。\n2. ZeRO-Offload 2.1 研究背景 在大模型训练时，内存容量很容易成为训练的瓶颈，即便是使用ZeRO机制将DP的内存拆分存储到不同的GPU上也难以应对继续增长的内存需求，但相对于GPU内存（显存）来说，CPU内存具有更低廉的价格更大的容量，将一部分显存消耗的压力释放到内存上成为了解决内存瓶颈的关键26。 2.2 实现方法 图. 全链接网络的数据流\nZeRO-Offload主要针对Model State（Parameters、Gradients、Optimizer State）所占用的内存空间进行卸载，针对例如Activation所占用的内存，由于其占比小于Model State，在本文中暂不考虑。\n如上图所示为使用Adam进行混合精度训练的全链接神经网络，M表示模型参数的数量，parameter16一般表示16位参数，例如FP16。\nparameter16与上次的activation16进行前向传播（FWD）的计算并获取新的activation16，并用于后向传播（BWD）的计算出gradient16，最后在Param Update阶段使用混合精度更新得到新的Model State（由于是混合精度，Parameter还需要进行一次float2half操作降低精度）。\n由于FWD和BWD的计算大多是矩阵运算，因此可以交由GPU进行计算，而Param Update一般是对参数进行数学运算，也可以放在CPU上进行，同时可以把Model State的值储存在CPU内存中\n通过Offload操作，每次运算需要GPU把gradient16传递给CPU，在CPU完成Param Update后将更新后的parameter16传回GPU，每次收发的数据量为2M\n在CPU与GPU进行数据交换的过程中，GPU和CPU可以继续异步的执行计算，实现数据传输与计算的并行\n图. ZeRO-Offload的训练时序图\nZeRO-Offload除了内存卸载技术，还继承了ZeRO技术，因此在多GPU条件下依旧会将DP所需的内存坟山到多个设备上进行分布式储存。 图. 在多个GPU上的ZeRO-Offload策略\n2.3 实验结论 ZeRO-Offload能确保CPU与GPU之间的通信量尽可能的小，避免数据交换成为瓶颈，并在最小通信开销条件下实现了最大化的内存节省\nZeRO-Offload会将一部分计算量和内存压力释放到CPU上，但与GPU相比，CPU的计算量要少几个数量级，以防止CPU成为计算瓶颈\n由于当前一个节点的配置可能是2个CPU+8个GPU，且CPU还需要负责任务调度等工作，使用CPU协助计算很容易使CPU成为并行计算的瓶颈\n由于需要CPU与GPU之间进行数据传输，因此该方法依赖PCIe的带宽，而且为了更好的训练模型，需要一个较大的的Batch Size设置22\n2.4 实验数据 2.4.1 不同方法的测试 图. 不同方法下可以运行的最大模型的参数量\n在单GPU机器上ZeRO-Offload的效果并不是最好的，单机的显存容量限制了可以运行最大模型参数量\n在多GPU机器上，由于ZeRO的加持下，将显存压力分散到多个GPU上，可以训练的最大模型参数两具有巨大的提升\n2.4.2 参数量级的测试 图. 单GPU的算力随着模型尺寸的增加变换\nZeRO-Offload在全部的模型尺寸上效果都优于对比的其他方法\n当模型的参数两超过8B时，几乎所有的并行方法效率都有所下降，ZeRO-Offload下降的原因可能是内存占用增加导致效率下降\n2.4.3 GPU数量的测试 图. 在10B参数的GPT-2模型下不同GPU数量上的表现\nZeRO-Offload最小支持到1-GPU即可运行10B参数的模型，但是ZeRO-2至少需要32个GPU才能运行10B参数规模的大模型\nGPU的增长与整体算力的增长基本呈线性关系\nZeRO-Offload在多张GPU上算力表现几乎相同（30-35TFLOPS）\n3. ZeRO-Infinity 3.1 研究背景 GPU显存的容量极大的限制了大模型的训练，近三年来模型的参数量级增长了1000倍，但GPU内存只增长了5倍，因此解决大模型训练过程中内存不足的问题成为了必要的基础技术22。\n即便是使用了ZeRO-Offload技术也无法应对10-100T级别的大模型，为了解决该问题，提出ZeRO-Infinity技术打破内存壁，极大的降低大模型对内存的依赖\n3.2 实现方法 图. 4路DP下的ZeRO-Infinity框架\n在不同的GPU之间使用网络进行All-Reduce操作同步参数，GPU内部通过PCIe将数据卸载到CPU内存中\n参考ZeRO-Offload技术，单一GPU上的内存占用可以将Model State卸载到CPU内存中\n以DGX-2为例，对Parameter和Gradient的传输速度要求是70GB/s，对Optimizer State的传输速度要求是1.5TB/s，对Activation Checkpoint的速度要求是1-4GB/s\n数据在CPU内存、GPU内存、NVMe之间的传输和计算可以是并行的\n如果要训练的某一层的参数量超过了单一GPU设备的内存容量，可以将该层拆分为多个子序列，并借助ZeRO-Infinity技术按顺序计算这些子序列，以完成较大层的计算\n3.3 实验结论 ZeRO-Infinity与ZeRO-Offload不同的是，ZeRO-Infinity可以将Activation Checkpoint卸载到CPU内存上\nZeRO-Infinity巧妙的利用AI训练时不同数据的需求时刻和需求带宽不一样，将数据转存在CPU内存或NVM上，充分利用各个存储介质的优势，ZeRO-Infinity会根据需要将数据卸载到CPU内存或NVMe上，以提高内存容量\nZeRO-Infinity支持一种新的GPU内存优化技术memory-centric tiling，以实现超大的单层网络内存管理，避免超大单层网络所需内存超出GPU最大显存容量\n经过ZeRO-Infinity优化，10T模型的Activation Checkpoint可以轻松的放在现在的DGX-2的1.5TB内存上，未来100T模型的Activation Checkpoint也可以放置在新的硬件设备上\n3.4 实验数据 3.4.1 GPU数量的测试 图. ZeRO-Infinity可以训练的模型参数量\nZeRO-Infinity支持32个DGX-2节点（512个GPU）下训练32T级别参数的模型，是当前最新的3D并行框架的50倍\nGPU数量与可以训练的参数量几乎是呈线性增长的\n预计在128个DGX-2（2048个GPU）上可以实现128T规模的模型运行\n3.4.2 参数量级的测试 图. 在512个GPU下ZeRO-Infinity与3D Parallelism的结果对比\n512个GPU个条件下ZeRO-Infinity支持训练20T参数量的模型，但3D Parallelism只支持到0.5T级别，ZeRO-Infinity是3D Parallelism的50倍\n随着模型参数量的增大，ZeRO-Infinity的GPU算力有所下降，可能还是单机的内存使用量增加影响了算力\n3.4.3 GPU数量与算力的测试 图. GPU数量与算力的关系\nZeRO-Infinity并行框架下，GPU的数量与总算力增长是超线性的，主要原因可能是随着GPU数量增多，每张GPU卡上的内存使用量会有所下降，从而导致每个GPU可用的内存容量更多 ","permalink":"https://www.zzudongxiang.com/posts/data-parallelism/","summary":"\u003cdiv\u003e\n\u003cblockquote\u003e\n\u003cp\u003e参考文献：\u003c/p\u003e\n\u003cp\u003e\u003cspan style=\"font-size: 14.4px\"\u003eTeam D, Majumder R, President V, et al. DeepSpeed: Extreme-scale model training for everyone\u003c/p\u003e\n\\[J\\]\u003cp\u003e. Microsoft, 2020.\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan style=\"font-size: 14.4px\"\u003eRajbhandari S, Rasley J, Ruwase O, et al. ZeRO: Memory optimizations Toward Training Trillion Parameter Models\u003c/p\u003e\n\\[C\\]\u003cp\u003e, 2020. IEEE, 2020-01-01.\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003eRen J, Rajbhandari S, Aminabadi R Y, et al. ZeRO-Offload: Democratizing Billion-Scale Model Training\u003c/p\u003e\n\\[J\\]\u003cp\u003e. \u003ca href=\"http://arXiv.org\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"\u003earXiv.org\u003c/a\u003e, 2021.\u003c/p\u003e\n\u003cp\u003e\u003cspan style=\"font-size: 14.4px\"\u003eRajbhandari S, Ruwase O, Rasley J, et al. ZeRO-Infinity: Breaking the GPU MemoryWall for Extreme Scale Deep Learning: SC\u0026rsquo; 21, November 14–19, 2021, St. Louis, MO, USA\u003c/p\u003e","title":"数据并行（Data Parallelism）"},{"content":" 1. HeteroG 参考文献：\nYi X, Zhang S, Luo Z, et al. Optimizing Distributed Training Deployment in Heterogeneous GPU Clusters: Proceedings of the 16th International Conference on emerging Networking EXperiments and Technologies\n\\[C\\], Barcelona, Spain, 2020. Association for Computing Machinery.\n一个集群中的GPU型号和性能可能都有所不同，但是在并行计算的时候往往假设每个参与并行的设备算力都是相等的，但是实际上由许多不同型号的GPU组成的集群仍然存在，为了解决这个问题，有相关的研究者提出了HeteroG方法，在异构集群上实现有效率的并行计算。\n图. HeteroG的工作流程图\n首先对开发者构建的网络进行分析，根据模型的需要决定是否需要进行MP\n然后根据策略将模型分发到各个设备上进行开销测试（Profiler）和仿真计算（Simulator）然后根据这个测试结果指定相应的并行策略（Strategy Maker）\n完成策略制定后重新对网络图进行重新编译（根据MP和DP的测算结果决定）然后开始并行计算\n这个工作主要由一个经过训练的神经网络完成\n最终实验结果证明与当前其他的并行策略相比，在异构集群的并行计算上有222%的性能提升。\n","permalink":"https://www.zzudongxiang.com/posts/heterogeneous-clusters/","summary":"\u003cdiv\u003e\n\u003ch1 id=\"1-heterog\"\u003e1. HeteroG\u003c/h1\u003e\n\u003cblockquote\u003e\n\u003cp\u003e参考文献：\u003c/p\u003e\n\u003cp\u003e\u003cspan style=\"font-size: 14.4px\"\u003eYi X, Zhang S, Luo Z, et al. Optimizing Distributed Training Deployment in Heterogeneous GPU Clusters: Proceedings of the 16th International Conference on emerging Networking EXperiments and Technologies\u003c/p\u003e\n\\[C\\]\u003cp\u003e, Barcelona, Spain, 2020. Association for Computing Machinery.\u003c/span\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e一个集群中的GPU型号和性能可能都有所不同，但是在并行计算的时候往往假设每个参与并行的设备算力都是相等的，但是实际上由许多不同型号的GPU组成的集群仍然存在，为了解决这个问题，有相关的研究者提出了\u003ccode\u003eHeteroG\u003c/code\u003e方法，在异构集群上实现有效率的并行计算。\u003c/p\u003e\n\u003cimg src=\"images/image-lqrb.png\" style=\"display: inline-block;width:50.0%\" /\u003e\n\u003cp\u003e图. HeteroG的工作流程图\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e首先对开发者构建的网络进行分析，根据模型的需要决定是否需要进行MP\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e然后根据策略将模型分发到各个设备上进行开销测试（Profiler）和仿真计算（Simulator）然后根据这个测试结果指定相应的并行策略（Strategy Maker）\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e完成策略制定后重新对网络图进行重新编译（根据MP和DP的测算结果决定）然后开始并行计算\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e这个工作主要由一个经过训练的神经网络完成\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e最终实验结果证明与当前其他的并行策略相比，在异构集群的并行计算上有222%的性能提升。\u003c/p\u003e\n\u003c/div\u003e","title":"异构集群（Heterogeneous Clusters）"},{"content":" 参考文献：\nShoeybi M, Patwary M, Puri R, et al. Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism\n\\[J\\]. ArXiv, 2020\n张量并行（Tensor Parallelism，TP）属于模型并行（Model Parallelism，MP）中的一种，通过对Tensor的拆分，将一次Tensor计算拆分到多台设备上进行并行的计算，并将计算结果最终合并为目标张量。\n1. Megatron-LM Megatron-LM是Nvidia提出的一种Tensor Parallelism方式，它的核心思想是将模型进行纵向分割（假定模型为由下向上的传递方式），Megatron-LM的TP主要针对基于Transformer，通过对Transformer中的Self-Attention和MLP进行拆分并行。\n1.1 研究背景 在研究MP技术时，从数学上对矩阵计算的角度上发现针对Transformer可以进行纵向分割，从而在纵向分割上实现并行加速，由于这种方法将一个张量分割为多个张量并行计算，因此该方法属于Tensor Parallelism。 1.2 实现方法 图. Tensor Parallelism对Transformer中两部分的并行过程\n针对Transformer中的MLP单元\nMLP在并行之前的运算过程可以表示为：Z=Dropout(GeLU(XA) B)，其中X为输入数据，Z为输出数据，A和B分别为神经网络的参数\n在并行时，可以将A矩阵按照列拆分为A=\n\\[A_1, A_2\\]两部分，并将其分别放置到两个设备中分别对输入的X进行计算，并分别获得结果Y_1=GeLU(X A_1)和Y_2=GeLU(X A_2)\n对矩阵B按照行拆分成两部分，并分别放置到两个设备中B=\n\\[B_1; B_2\\] 假设输入的X矩阵的维度为m x n大小的，则可用如下公式描述输入矩阵A\n$$X=\\left[ \\begin{matrix} x_{1,1} \u0026 \\cdots \u0026 x_{1,n} \\\\ \\vdots \u0026 \\ddots \u0026 \\vdots \\\\ x_{m,1} \u0026 \\cdots \u0026 x_{m,n} \\\\ \\end{matrix} \\right] =\\left[ \\begin{matrix} X_1\\\\X_2 \\end{matrix} \\right]$$ 假设MLP中的矩阵A的维度为n x k，且定义h=k/2，则定义矩阵A如下：\n$$X=\\left[ \\begin{matrix} x_{1,1} \u0026 \\cdots \u0026 x_{1,n} \\\\ \\vdots \u0026 \\ddots \u0026 \\vdots \\\\ x_{m,1} \u0026 \\cdots \u0026 x_{m,n} \\\\ \\end{matrix} \\right] =\\left[ \\begin{matrix} X_1\\\\X_2 \\end{matrix} \\right]$$ 由此可以分别计算出Y_1和Y_2（假定对A_1和A_2拆分后空白位置补0），可表示为：\n$$Y_1=\\left[ \\begin{matrix} X_1 A_1 \u0026 0 \\\\ X_2 A_1 \u0026 0 \\end{matrix} \\right] , Y_2=\\left[ \\begin{matrix} 0 \u0026 X_1 A_2 \\\\ 0 \u0026 X_2 A_2 \\end{matrix} \\right]$$ GeLU()操作是针对矩阵中的每一个元素分别进行的，这里对矩阵的维度和并行无任何影响，因此暂不考虑GeLU()函数\n由以上可以计算得到Z_1和Z_2如下所示：\n$$Z_1=\\left[ \\begin{matrix} X_1 A_1 B_1 \u0026 0 \\\\ X_2 A_1 B_1 \u0026 0 \\end{matrix} \\right] , Z_2=\\left[ \\begin{matrix} 0 \u0026 X_1 A_2 B_2 \\\\ 0 \u0026 X_2 A_2 B_2 \\end{matrix} \\right]$$ 依照此方法将矩阵A按照列的方式切割为A=\n\\[A_1, A_2\\] 在每一步计算时都可以独立进行，直到得到最终的结果Z_1和Z_2\n如果将矩阵A按照行的方式切割为A=\n\\[A_1; A_2\\]，则在计算Y_1时需要取出X的每一行与A的每一列，又由于A的每一列都分别储存在两个设备上，因此需要在这个阶段增加通信以完成Y_1和Y_2的计算\nSelf-Attention模块的并行拆分方法与MLP类似\n1.3 实验结论 由于TP的自身特性，每一层Transformer的输出都要进行一次All-Reduce，相比较DP而言，会增加通信量，但是其优点是当Transformer的参数量大到一张GPU放不下时，可以使用TP方法放到多张GPU上训练\n没办法进行数据通信并行和数据计算并行，必须要等到数据发送/接收完成后才能继续下一步\n以单GPU的39TFLOPS算力（30%硬件峰值性能）为基线，集群的最高算力达到15.1PFLOPS，达到了理论计算峰值的76%\n获得了几乎线性的GPU数量与算力提升的关系\n1.4 实验数据 1.4.1 GPU数量与算力的关系 图. 并行的GPU数量与总算力的关系\n在1B参数模型上进行GPU训练测试，蓝色曲线为MP（TP）方法，绿色曲线为MP+DP方法，由图表可知，GPU数量的增长与总算力增长的关系几乎是线性的\n并行的GPU数量与总算力不呈线性关系的原因是TP过程中通信造成的算力下降\n当GPU数量增长到64时，MP+DP的模式的算力高于MP本身，具体原因参考下面的实际实验结果\n1.4.2 GPU数量与效率的关系 图. 并行的GPU数量与并行效率的关系\n蓝色为TP，GPU数量为1时表示不使用TP算法；绿色为TP+DP，GPU数量为64时表示纯DP\n当GPU数量为128时表示，每两个GPU之间形成TP并行，64组GPU之间形成DP并行\n由于DP可以进行异步，而TP必须等待上一层并行完成All-Reduce后才进行下一步操作，因此当GPU数量为64时，DP+MP的效率略小于单机的MP效率\n","permalink":"https://www.zzudongxiang.com/posts/tensor-parallelism/","summary":"\u003cdiv\u003e\n\u003cblockquote\u003e\n\u003cp\u003e参考文献：\u003c/p\u003e\n\u003cp\u003e\u003cspan style=\"font-size: 14.4px\"\u003eShoeybi M, Patwary M, Puri R, et al. Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism\u003c/p\u003e\n\\[J\\]\u003cp\u003e. ArXiv, 2020\u003c/span\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e张量并行（Tensor Parallelism，TP）属于模型并行（Model Parallelism，MP）中的一种，通过对Tensor的拆分，将一次Tensor计算拆分到多台设备上进行并行的计算，并将计算结果最终合并为目标张量。\u003c/p\u003e\n\u003ch2 id=\"1-megatron-lm\"\u003e1. Megatron-LM\u003c/h2\u003e\n\u003cp\u003eMegatron-LM是Nvidia提出的一种Tensor Parallelism方式，它的核心思想是将模型进行纵向分割（假定模型为由下向上的传递方式），Megatron-LM的TP主要针对基于Transformer，通过对Transformer中的Self-Attention和MLP进行拆分并行。\u003c/p\u003e\n\u003ch3 id=\"11-研究背景\"\u003e1.1 研究背景\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e在研究MP技术时，从数学上对矩阵计算的角度上发现针对Transformer可以进行纵向分割，从而在纵向分割上实现并行加速，由于这种方法将一个张量分割为多个张量并行计算，因此该方法属于Tensor Parallelism。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"12-实现方法\"\u003e1.2 实现方法\u003c/h3\u003e\n\u003cimg src=\"images/image-wtqh.png\" style=\"display: inline-block\" width=\"597\" height=\"631\" /\u003e\n\u003cp\u003e图. Tensor Parallelism对Transformer中两部分的并行过程\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e针对Transformer中的MLP单元\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eMLP在并行之前的运算过程可以表示为：Z=Dropout(GeLU(XA) B)，其中X为输入数据，Z为输出数据，A和B分别为神经网络的参数\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e在并行时，可以将A矩阵按照列拆分为A=\u003c/p\u003e\n\\[A_1, A_2\\]\u003cp\u003e两部分，并将其分别放置到两个设备中分别对输入的X进行计算，并分别获得结果Y_1=GeLU(X A_1)和Y_2=GeLU(X A_2)\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e对矩阵B按照行拆分成两部分，并分别放置到两个设备中B=\u003c/p\u003e\n\\[B_1; B_2\\]\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e假设输入的X矩阵的维度为m x n大小的，则可用如下公式描述输入矩阵A\u003c/p\u003e\n$$X=\\left[ \\begin{matrix} x_{1,1} \u0026 \\cdots \u0026 x_{1,n} \\\\ \\vdots \u0026 \\ddots \u0026 \\vdots \\\\ x_{m,1} \u0026 \\cdots \u0026 x_{m,n} \\\\ \\end{matrix} \\right] =\\left[ \\begin{matrix} X_1\\\\X_2 \\end{matrix} \\right]$$\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e假设MLP中的矩阵A的维度为n x k，且定义h=k/2，则定义矩阵A如下：\u003c/p\u003e","title":"张量并行（Tensor Parallelism）"},{"content":"MathJax是一款运行于 Web 浏览器当中的开源 JavaScript 数学符号渲染引擎，通过它可以方便的在现代 Web 浏览器当中显示数学公式，目前已经能够解析 LaTex、MathML 等标记语言。MathJax 项目发源于 2009 年，目前由 NumFOCUS 基金会主持，并且得到了 MathJax 联盟的支持，该联盟是美国数学协会（AMS）和 工业与应用数学协会（SIAM）的共同合资企业。\nLaTeX是一种高质量的排版格式，可以生成复杂的表格与数学公式，是当前电子与数学出版行业的事实标准。本文以 Pandoc作为 LaTex 渲染引擎（一款用于标记语言文档转换的命令行工具），分门别类的总结了撰写数学公式所需要经常使用到的 LaTeX 语法，方便写作相关科技类文章时随手查阅。\n1. 希腊字母 序号 标准符号 LaTeX 首字母大写 LaTeX 使用 var 前缀 LaTeX 读音 1 $\\alpha$ \\alpha /ˈælfə/ 2 $\\beta$ \\beta /ˈbeɪtə/ 3 $\\gamma$ \\gamma $\\Gamma$ \\Gamma $\\varGamma$ \\varGamma /ˈɡæmə/ 4 $\\delta$ \\delta $\\Delta$ \\Delta $\\varDelta$ \\varDelta /ˈdɛltə/ 5 $\\epsilon$ \\epsilon $\\varepsilon$ \\varepsilon /ˈɛpsɪlɒn/ 6 $\\zeta$ \\zeta /ˈzeɪtə/ 7 $\\eta$ \\eta /ˈeɪtə/ 8 $\\theta$ \\theta $\\Theta$ \\Theta $\\vartheta$、$\\varTheta$ \\vartheta、\\varTheta /ˈθiːtə/ 9 $\\iota$ \\iota /aɪˈoʊtə/ 10 $\\kappa$ \\kappa $\\varkappa$ \\varkappa /ˈkæpə/ 11 $\\lambda$ \\lambda $\\Lambda$ \\Lambda $\\varLambda$ \\varLambda /ˈlæmdə/ 12 $\\mu$ \\mu /mjuː/ 13 $\\nu$ \\nu /njuː/ 14 $\\xi$ \\xi $\\Xi$ \\Xi $\\varXi$ \\varXi /zaɪ, ksaɪ/ 15 $o$ o $O$ O /ˈɒmɪkrɒn/ 16 $\\pi$ \\pi $\\Pi$ \\Pi $\\varpi$、$\\varPi$ \\varpi、\\varPi /paɪ/ 17 $\\rho$ \\rho $\\varrho$ \\varrho /roʊ/ 18 $\\sigma$ \\sigma $\\Sigma$ \\Sigma $\\varsigma$、$\\varSigma$ \\varsigma、\\varSigma /ˈsɪɡmə/ 19 $\\tau$ \\tau /taʊ, tɔː/ 20 $\\upsilon$ \\upsilon $\\Upsilon$ \\Upsilon $\\varUpsilon$ \\varUpsilon /ˈʌpsɪlɒn/ 21 $\\phi$ \\phi $\\Phi$ \\Phi $\\varphi$、$\\varPhi$ \\varphi、\\varPhi /faɪ/ 22 $\\chi$ \\chi /kaɪ/ 23 $\\psi$ \\psi $\\Psi$ \\Psi $\\varPsi$ \\varPsi /psaɪ/ 24 $\\omega$ \\omega $\\Omega$ \\Omega $\\varOmega$ \\varOmega /oʊˈmeɪɡə/ 25 $\\digamma$ \\digamma /daɪ'gæmə/ 2. 二元运算符 序号 符号 LaTeX 序号 符号 LaTeX 1 $+$ + 20 $\\bullet$ \\bullet 2 $-$ - 21 $\\oplus$ \\oplus 3 $\\times$ \\times 22 $\\ominus$ \\ominus 4 $\\div$ \\div 23 $\\odot$ \\odot 5 $\\pm$ \\pm 24 $\\oslash$ \\oslash 6 $\\mp$ \\mp 25 $\\otimes$ \\otimes 7 $\\triangleleft$ \\triangleleft 26 $\\bigcirc$ \\bigcirc 8 $\\triangleright$ \\triangleright 27 $\\diamond$ \\diamond 9 $\\cdot$ \\cdot 28 $\\uplus$ \\uplus 10 $\\setminus$ \\setminus 29 $\\bigtriangleup$ \\bigtriangleup 11 $\\star$ \\star 30 $\\bigtriangledown$ \\bigtriangledown 12 $\\ast$ \\ast 31 $\\lhd$ \\lhd 13 $\\cup$ \\cup 32 $\\rhd$ \\rhd 14 $\\cap$ \\cap 33 $\\unlhd$ \\unlhd 15 $\\sqcup$ \\sqcup 34 $\\unrhd$ \\unrhd 16 $\\sqcap$ \\sqcap 35 $\\amalg$ \\amalg 17 $\\vee$ \\vee 36 $\\wr$ \\wr 18 $\\wedge$ \\wedge 37 $\\dagger$ \\dagger 19 $\\circ$ \\circ 38 $\\ddagger$ \\ddagger 3. 二元关系符 序号 符号 LaTeX 序号 符号 LaTeX 1 $=$ = 49 $\\gneq$ \\gneq 2 $\\ne$ \\ne 50 $\\geqq$ \\geqq 3 $\\neq$ \\neq 51 $\\ngeq$ \\ngeq 4 $\\equiv$ \\equiv 52 $\\ngeqq$ \\ngeqq 5 $\\not\\equiv$ \\not\\equiv 53 $\\gneqq$ \\gneqq 6 $\\doteq$ \\doteq 54 $\\gvertneqq$ \\gvertneqq 7 $\\doteqdot$ \\doteqdot 55 $\\lessgtr$ \\lessgtr 8 $\\overset{\\underset{\\mathrm{def}}{}}{=}$ \\overset{\\underset{\\mathrm{def}}{}}{=} 56 $\\lesseqgtr$ \\lesseqgtr 9 $:=$ := 57 $\\lesseqqgtr$ \\lesseqqgtr 10 $\\sim$ \\sim 58 $\\gtrless$ \\gtrless 11 $\\nsim$ \\nsim 59 $\\gtreqless$ \\gtreqless 12 $\\backsim$ \\backsim 60 $\\gtreqqless$ \\gtreqqless 13 $\\thicksim$ \\thicksim 61 $\\leqslant$ \\leqslant 14 $\\simeq$ \\simeq 62 $\\nleqslant$ \\nleqslant 15 $\\backsimeq$ \\backsimeq 63 $\\eqslantless$ \\eqslantless 16 $\\eqsim$ \\eqsim 64 $\\geqslant$ \\geqslant 17 $\\cong$ \\cong 65 $\\ngeqslant$ \\ngeqslant 18 $\\ncong$ \\ncong 66 $\\eqslantgtr$ \\eqslantgtr 19 $\\approx$ \\approx 67 $\\lesssim$ \\lesssim 20 $\\thickapprox$ \\thickapprox 68 $\\lnsim$ \\lnsim 21 $\\approxeq$ \\approxeq 69 $\\lessapprox$ \\lessapprox 22 $\\asymp$ \\asymp 70 $\\lnapprox$ \\lnapprox 23 $\\propto$ \\propto 71 $\\gtrsim$ \\gtrsim 24 $\\varpropto$ \\varpropto 72 $\\gnsim$ \\gnsim 25 $\u0026lt;$ \u0026lt; 73 $\\gtrapprox$ \\gtrapprox 26 $\\nless$ \\nless 74 $\\gnapprox$ \\gnapprox 27 $\\ll$ \\ll 75 $\\prec$ \\prec 28 $\\not\\ll$ \\not\\ll 76 $\\nprec$ \\nprec 29 $\\lll$ \\lll 77 $\\preceq$ \\preceq 30 $\\not\\lll$ \\not\\lll 78 $\\npreceq$ \\npreceq 31 $\\lessdot$ \\lessdot 79 $\\precneqq$ \\precneqq 32 $\u0026gt;$ \u0026gt; 80 $\\succ$ \\succ 33 $\\ngtr$ \\ngtr 81 $\\nsucc$ \\nsucc 34 $\\gg$ \\gg 82 $\\succeq$ \\succeq 35 $\\not\\gg$ \\not\\gg 83 $\\nsucceq$ \\nsucceq 36 $\\ggg$ \\ggg 84 $\\succneqq$ \\succneqq 37 $\\not\\ggg$ \\not\\ggg 85 $\\preccurlyeq$ \\preccurlyeq 38 $\\gtrdot$ \\gtrdot 86 $\\curlyeqprec$ \\curlyeqprec 39 $\\le$ \\le 87 $\\succcurlyeq$ \\succcurlyeq 40 $\\leq$ \\leq 88 $\\curlyeqsucc$ \\curlyeqsucc 41 $\\lneq$ \\lneq 89 $\\precsim$ \\precsim 42 $\\leqq$ \\leqq 90 $\\precnsim$ \\precnsim 43 $\\nleq$ \\nleq 91 $\\precapprox$ \\precapprox 44 $\\nleqq$ \\nleqq 92 $\\precnapprox$ \\precnapprox 45 $\\lneqq$ \\lneqq 93 $\\succsim$ \\succsim 46 $\\lvertneqq$ \\lvertneqq 94 $\\succnsim$ \\succnsim 47 $\\ge$ \\ge 95 $\\succapprox$ \\succapprox 48 $\\geq$ \\geq 96 $\\succnapprox$ \\succnapprox 4. 逻辑符号 序号 符号 LaTeX 序号 符号 LaTeX 1 $\\forall$ \\forall 20 $\\neg$ \\neg 2 $\\exists$ \\exists 21 $\\not\\operatorname{R}$ \\not\\operatorname{R} 3 $\\nexists$ \\nexists 22 $\\bot$ \\bot 4 $\\therefore$ \\therefore 23 $\\top$ \\top 5 $\\because$ \\because 24 $\\vdash$ \\vdash 6 $\\And$ \\And 25 $\\dashv$ \\dashv 7 $\\lor$ \\lor 26 $\\vDash$ \\vDash 8 $\\vee$ \\vee 27 $\\Vdash$ \\Vdash 9 $\\curlyvee$ \\curlyvee 28 $\\models$ \\models 10 $\\bigvee$ \\bigvee 29 $\\Vvdash$ \\Vvdash 11 $\\land$ \\land 30 $\\nvdash$ \\nvdash 12 $\\wedge$ \\wedge 31 $\\nVdash$ \\nVdash 13 $\\curlywedge$ \\curlywedge 32 $\\nvDash$ \\nvDash 14 $\\bigwedge$ \\bigwedge 33 $\\nVDash$ \\nVDash 15 $\\bar{q}$ \\bar{q} 34 $\\ulcorner$ \\ulcorner 16 $\\bar{abc}$ \\bar{abc} 35 $\\urcorner$ \\urcorner 17 $\\overline{q}$ \\overline{q} 36 $\\llcorner$ \\llcorner 18 $\\overline{abc}$ \\overline{abc} 37 $\\lrcorner$ \\lrcorner 19 $\\lnot$ \\lnot 5. 集合符号 序号 符号 LaTeX 序号 符号 LaTeX 1 $\\{ \\}$ \\{ \\} 23 $\\sqsubset$ \\sqsubset 2 $\\emptyset$ \\emptyset 24 $\\supset$ \\supset 3 $\\varnothing$ \\varnothing 25 $\\Supset$ \\Supset 4 $\\in$ \\in 26 $\\sqsupset$ \\sqsupset 5 $\\notin$ \\notin 27 $\\subseteq$ \\subseteq 6 $\\ni$ \\ni 28 $\\nsubseteq$ \\nsubseteq 7 $\\cap$ \\cap 29 $\\subsetneq$ \\subsetneq 8 $\\Cap$ \\Cap 30 $\\varsubsetneq$ \\varsubsetneq 9 $\\sqcap$ \\sqcap 31 $\\sqsubseteq$ \\sqsubseteq 10 $\\bigcap$ \\bigcap 32 $\\supseteq$ \\supseteq 11 $\\cup$ \\cup 33 $\\nsupseteq$ \\nsupseteq 12 $\\Cup$ \\Cup 34 $\\supsetneq$ \\supsetneq 13 $\\sqcup$ \\sqcup 35 $\\varsupsetneq$ \\varsupsetneq 14 $\\bigcup$ \\bigcup 36 $\\sqsupseteq$ \\sqsupseteq 15 $\\bigsqcup$ \\bigsqcup 37 $\\subseteqq$ \\subseteqq 16 $\\uplus$ \\uplus 38 $\\nsubseteqq$ \\nsubseteqq 17 $\\biguplus$ \\biguplus 39 $\\subsetneqq$ \\subsetneqq 18 $\\setminus$ \\setminus 40 $\\varsubsetneqq$ \\varsubsetneqq 19 $\\smallsetminus$ \\smallsetminus 41 $\\supseteqq$ \\supseteqq 20 $\\times$ \\times 42 $\\nsupseteqq$ \\nsupseteqq 21 $\\subset$ \\subset 43 $\\supsetneqq$ \\supsetneqq 22 $\\Subset$ \\Subset 44 $\\varsupsetneqq$ \\varsupsetneqq 6. 箭头符号 序号 符号 LaTeX 序号 符号 LaTeX 1 $\\Rrightarrow$ \\Rrightarrow 36 $\\longmapsto$ \\longmapsto 2 $\\Lleftarrow$ \\Lleftarrow 37 $\\rightharpoonup$ \\rightharpoonup 3 $\\Rightarrow$ \\Rightarrow 38 $\\rightharpoondown$ \\rightharpoondown 4 $\\nRightarrow$ \\nRightarrow 39 $\\leftharpoonup$ \\leftharpoonup 5 $\\Longrightarrow$ \\Longrightarrow 40 $\\leftharpoondown$ \\leftharpoondown 6 $\\implies$ \\implies 41 $\\upharpoonleft$ \\upharpoonleft 7 $\\Leftarrow$ \\Leftarrow 42 $\\upharpoonright$ \\upharpoonright 8 $\\nLeftarrow$ \\nLeftarrow 43 $\\downharpoonleft$ \\downharpoonleft 9 $\\Longleftarrow$ \\Longleftarrow 44 $\\downharpoonright$ \\downharpoonright 10 $\\Leftrightarrow$ \\Leftrightarrow 45 $\\rightleftharpoons$ \\rightleftharpoons 11 $\\nLeftrightarrow$ \\nLeftrightarrow 46 $\\leftrightharpoons$ \\leftrightharpoons 12 $\\Longleftrightarrow$ \\Longleftrightarrow 47 $\\curvearrowleft$ \\curvearrowleft 13 $\\iff$ \\iff 48 $\\circlearrowleft$ \\circlearrowleft 14 $\\Uparrow$ \\Uparrow 49 $\\Lsh$ \\Lsh 15 $\\Downarrow$ \\Downarrow 50 $\\upuparrows$ \\upuparrows 16 $\\Updownarrow$ \\Updownarrow 51 $\\rightrightarrows$ \\rightrightarrows 17 $\\rightarrow$ \\rightarrow 52 $\\rightleftarrows$ \\rightleftarrows 18 $\\to$ \\to 53 $\\rightarrowtail$ \\rightarrowtail 19 $\\nrightarrow$ \\nrightarrow 54 $\\looparrowright$ \\looparrowright 20 $\\longrightarrow$ \\longrightarrow 55 $\\curvearrowright$ \\curvearrowright 21 $\\leftarrow$ \\leftarrow 56 $\\circlearrowright$ \\circlearrowright 22 $\\gets$ \\gets 57 $\\Rsh$ \\Rsh 23 $\\nleftarrow$ \\nleftarrow 58 $\\downdownarrows$ \\downdownarrows 24 $\\longleftarrow$ \\longleftarrow 59 $\\leftleftarrows$ \\leftleftarrows 25 $\\leftrightarrow$ \\leftrightarrow 60 $\\leftrightarrows$ \\leftrightarrows 26 $\\nleftrightarrow$ \\nleftrightarrow 61 $\\leftarrowtail$ \\leftarrowtail 27 $\\longleftrightarrow$ \\longleftrightarrow 62 $\\looparrowleft$ \\looparrowleft 28 $\\uparrow$ \\uparrow 63 $\\hookrightarrow$ \\hookrightarrow 29 $\\downarrow$ \\downarrow 64 $\\hookleftarrow$ \\hookleftarrow 30 $\\updownarrow$ \\updownarrow 65 $\\multimap$ \\multimap 31 $\\nearrow$ \\nearrow 66 $\\leftrightsquigarrow$ \\leftrightsquigarrow 32 $\\swarrow$ \\swarrow 67 $\\rightsquigarrow$ \\rightsquigarrow 33 $\\nwarrow$ \\nwarrow 68 $\\twoheadrightarrow$ \\twoheadrightarrow 34 $\\searrow$ \\searrow 69 $\\twoheadleftarrow$ \\twoheadleftarrow 35 $\\mapsto$ \\mapsto 7. 特殊符号 序号 符号 LaTeX 序号 符号 LaTeX 1 $\\infty$ \\infty 33 $\\flat$ \\flat 2 $\\aleph$ \\aleph 34 $\\natural$ \\natural 3 $\\complement$ \\complement 35 $\\sharp$ \\sharp 4 $\\backepsilon$ \\backepsilon 36 $\\diagup$ \\diagup 5 $\\eth$ \\eth 37 $\\diagdown$ \\diagdown 6 $\\Finv$ \\Finv 38 $\\centerdot$ \\centerdot 7 $\\hbar$ \\hbar 39 $\\ltimes$ \\ltimes 8 $\\Im$ \\Im 40 $\\rtimes$ \\rtimes 9 $\\imath$ \\imath 41 $\\leftthreetimes$ \\leftthreetimes 10 $\\jmath$ \\jmath 42 $\\rightthreetimes$ \\rightthreetimes 11 $\\Bbbk$ \\Bbbk 43 $\\eqcirc$ \\eqcirc 12 $\\ell$ \\ell 44 $\\circeq$ \\circeq 13 $\\mho$ \\mho 45 $\\triangleq$ \\triangleq 14 $\\wp$ \\wp 46 $\\bumpeq$ \\bumpeq 15 $\\Re$ \\Re 47 $\\Bumpeq$ \\Bumpeq 16 $\\circledS$ \\circledS 48 $\\doteqdot$ \\doteqdot 17 $\\amalg$ \\amalg 49 $\\risingdotseq$ \\risingdotseq 18 $\\%$ \\% 50 $\\fallingdotseq$ \\fallingdotseq 19 $\\dagger$ \\dagger 51 $\\intercal$ \\intercal 20 $\\ddagger$ \\ddagger 52 $\\barwedge$ \\barwedge 21 $\\ldots$ \\ldots 53 $\\veebar$ \\veebar 22 $\\cdots$ \\cdots 54 $\\doublebarwedge$ \\doublebarwedge 23 $\\smile$ \\smile 55 $\\between$ \\between 24 $\\frown$ \\frown 56 $\\pitchfork$ \\pitchfork 25 $\\wr$ \\wr 57 $\\vartriangleleft$ \\vartriangleleft 26 $\\triangleleft$ \\triangleleft 58 $\\ntriangleleft$ \\ntriangleleft 27 $\\triangleright$ \\triangleright 59 $\\vartriangleright$ \\vartriangleright 28 $\\diamondsuit$ \\diamondsuit 60 $\\ntriangleright$ \\ntriangleright 29 $\\heartsuit$ \\heartsuit 61 $\\trianglelefteq$ \\trianglelefteq 30 $\\clubsuit$ \\clubsuit 62 $\\ntrianglelefteq$ \\ntrianglelefteq 31 $\\spadesuit$ \\spadesuit 63 $\\trianglerighteq$ \\trianglerighteq 32 $\\Game$ \\Game 64 $\\ntrianglerighteq$ \\ntrianglerighteq 8. 分数 类型 符号 LaTeX 分数 $\\frac{2}{4}x=0.5x or {2 \\over 4}x=0.5x$ \\frac{2}{4}x=0.5x or {2 \\over 4}x=0.5x 小型分数 $\\tfrac{2}{4}x = 0.5x$ \\tfrac{2}{4}x = 0.5x 大型分数 （嵌套） $\\cfrac{2}{c + \\cfrac{2}{d + \\cfrac{2}{4}}} = a$ \\cfrac{2}{c + \\cfrac{2}{d + \\cfrac{2}{4}}} = a 9. 数值函数 符号 LaTeX $\\exp_a b = a^b, \\exp b = e^b, 10^m$ \\exp_a b = a^b, \\exp b = e^b, 10^m $\\ln c, \\lg d = \\log e, \\log_{10} f$ \\ln c, \\lg d = \\log e, \\log_{10} f $\\sin a, \\cos b, \\tan c, \\cot d, \\sec e, \\csc f$ \\sin a, \\cos b, \\tan c, \\cot d, \\sec e, \\csc f $\\arcsin a, \\arccos b, \\arctan c$ \\arcsin a, \\arccos b, \\arctan c $\\operatorname{arccot} d, \\operatorname{arcsec} e, \\operatorname{arccsc} f$ \\operatorname{arccot} d, \\operatorname{arcsec} e, \\operatorname{arccsc} f $\\sinh a, \\cosh b, \\tanh c, \\coth d$ \\sinh a, \\cosh b, \\tanh c, \\coth d $\\operatorname{sh}k, \\operatorname{ch}l, \\operatorname{th}m, \\operatorname{coth}n$ \\operatorname{sh}k, \\operatorname{ch}l, \\operatorname{th}m, \\operatorname{coth}n $\\operatorname{argsh}o, \\operatorname{argch}p, \\operatorname{argth}q$ \\operatorname{argsh}o, \\operatorname{argch}p, \\operatorname{argth}q $\\operatorname{sgn}r, \\left\\vert s \\right\\vert$ \\operatorname{sgn}r, \\left\\vert s \\right\\vert $\\min(x,y), \\max(x,y)$ \\min(x,y), \\max(x,y) 如果需要使用特殊的函数符号，那么可以采用 \\operatorname{} 命令进行自定义：\n符号 LaTeX $\\operatorname{mydefine}x$ \\operatorname{mydefine}x 10. 根式 符号 LaTeX 符号 LaTeX $\\surd$ \\surd $\\sqrt[n]{\\pi}$ \\sqrt[n]{\\pi} $\\sqrt{\\pi}$ \\sqrt{\\pi} $\\sqrt[3]{\\frac{x^3+y^3}{2}}$ \\sqrt[3]{\\frac{x^3+y^3}{2}}*_ 11. 微分与导数 符号 LaTeX $dt, \\mathrm{d}t, \\partial t, \\nabla\\psi$ dt, \\mathrm{d}t, \\partial t, \\nabla\\psi $dy/dx, \\mathrm{d}y/\\mathrm{d}x, \\frac{dy}{dx}, \\frac{\\mathrm{d}y}{\\mathrm{d}x}, \\frac{\\partial^2}{\\partial x_1\\partial x_2}y$ dy/dx, \\mathrm{d}y/\\mathrm{d}x, \\frac{dy}{dx}, \\frac{\\mathrm{d}y}{\\mathrm{d}x}, \\frac{\\partial^2}{\\partial x_1\\partial x_2}y $\\prime, \\backprime, f^\\prime, f', f'', f^{(3)}, \\dot y, \\ddot y$ \\prime, \\backprime, f^\\prime, f', f'', f^{(3)}, \\dot y, \\ddot y 12. 模运算 符号 LaTeX $s_k \\equiv 0 \\pmod{m}$ s_k \\equiv 0 \\pmod{m} $a \\bmod b$ a \\bmod b $\\gcd(m, n), \\operatorname{lcm}(m, n)$ \\gcd(m, n), \\operatorname{lcm}(m, n) $\\mid, \\nmid, \\shortmid, \\nshortmid$ \\mid, \\nmid, \\shortmid, \\nshortmid 13. 极限 符号 LaTeX $\\lim_{n \\to \\infty}x_n$ \\lim_{n \\to \\infty}x_n $\\textstyle \\lim_{n \\to \\infty}x_n$ \\textstyle \\lim_{n \\to \\infty}x_n 14. 范围与预测 符号 LaTeX $\\min x, \\max y, \\inf s, \\sup t$ \\min x, \\max y, \\inf s, \\sup t $\\lim u, \\liminf v, \\limsup w$ \\lim u, \\liminf v, \\limsup w $\\dim p, \\deg q, \\det m, \\ker\\phi$ \\dim p, \\deg q, \\det m, \\ker\\phi $\\Pr j, \\hom l, \\lVert z \\rVert, \\arg z$ \\Pr j, \\hom l, \\lVert z \\rVert, \\arg z 15. 积分 符号 LaTeX $\\int\\limits_{1}^{3}\\frac{e^3/x}{x^2}\\, dx$ \\int\\limits_{1}^{3}\\frac{e^3/x}{x^2}\\, dx $\\int_{1}^{3}\\frac{e^3/x}{x^2}\\, dx$ \\int_{1}^{3}\\frac{e^3/x}{x^2}\\, dx $\\textstyle \\int\\limits_{-N}^{N} e^x dx$ \\textstyle \\int\\limits_{-N}^{N} e^x dx $\\textstyle \\int_{-N}^{N} e^x dx$ \\textstyle \\int_{-N}^{N} e^x dx $\\iint\\limits_D dx\\,dy$ \\iint\\limits_D dx\\,dy $\\iiint\\limits_E dx\\,dy\\,dz$ \\iiint\\limits_E dx\\,dy\\,dz $\\int_{(x,y)\\in C} x^3\\, dx + 4y^2\\,dy$ \\int_{(x,y)\\in C} x^3\\, dx + 4y^2\\, dy $\\oint_{(x,y)\\in C} x^3\\, dx + 4y^2\\,dy$ \\oint_{(x,y)\\in C} x^3\\, dx + 4y^2\\, dy 注意：积分符号采用 \\int\\_{}^{} 命令调用，双重积分符号采用 \\iint\\_{}^{}，以此类推，最高可以支持四重积分。\n16. 大型运算符 分类 符号 LaTeX 符号 LaTeX 求和 $\\sum_{a}^{b}$ \\sum_{a}^{b} $\\textstyle \\sum_{a}^{b}$ \\textstyle \\sum_{a}^{b} 连乘积 $\\prod_{a}^{b}$ \\prod_{a}^{b} $\\textstyle \\prod_{a}^{b}$ \\textstyle \\prod_{a}^{b} 余积 $\\coprod_{a}^{b}$ \\coprod_{a}^{b} $\\textstyle \\coprod_{a}^{b}$ \\textstyle \\coprod_{a}^{b} 并集 $\\bigcup_{a}^{b}$ \\bigcup_{a}^{b} $\\textstyle \\bigcup_{a}^{b}$ \\textstyle \\bigcup_{a}^{b} 交集 $\\bigcap_{a}^{b}$ \\bigcap_{a}^{b} $\\textstyle \\bigcap_{a}^{b}$ \\textstyle \\bigcap_{a}^{b} 析取 $\\bigvee_{a}^{b}$ \\bigvee_{a}^{b} $\\textstyle \\bigvee_{a}^{b}$ \\textstyle \\bigvee_{a}^{b} 合取 $\\bigwedge_{a}^{b}$ \\bigwedge_{a}^{b} $\\textstyle \\bigwedge_{a}^{b}$ \\textstyle \\bigwedge_{a}^{b} 17. 上下标 类型 符号 代码 上标 $a^2$ $a^{x+3}$ a^2 a^{x+3} 下标 $a_2$ a_2 组合 $10^{30} a^{2+2}a{i,j} b{f'}$ 10^{30} a^{2+2} a{i,j} b{f'} 上下标混合 $x_2^3$ ${x_2}^3$ x_2^3 {x_2}^3 上标的上标 $10^{10^{8}}$ 10^{10^{8}} 顶标底标 $\\overset{\\alpha}{\\omega}$ $\\underset{\\alpha}{\\omega}$ $\\overset{\\alpha}{\\underset{\\gamma}{\\omega}}$ $\\stackrel{\\alpha}{\\omega}$ \\overset{\\alpha}{\\omega} \\underset{\\alpha}{\\omega} \\overset{\\alpha}{\\underset{\\gamma}{\\omega}} \\stackrel{\\alpha}{\\omega} 导数 $x', y'', f', f''$ $x^\\prime, y^{\\prime\\prime}$ x', y'', f', f'' x^\\prime, y^{\\prime\\prime} 导数点 $\\dot{x}, \\ddot{x}$ \\dot{x}, \\ddot{x} 上下划线与向量 $\\hat a \\ \\bar b \\ \\vec c$ $\\overrightarrow{a b} \\ \\overleftarrow{c d} \\ \\widehat{d e f}$ $\\overline{g h i} \\ \\underline{j k l}$ \\hat a \\ \\bar b \\ \\vec c \\overrightarrow{a b} \\ \\overleftarrow{c d} \\ \\widehat{d e f} \\overline{g h i} \\ \\underline{j k l} 弧度 $\\overset{\\frown} {AB}$ \\overset{\\frown} {AB} 箭头 $A \\xleftarrow{n+\\mu-1} B \\xrightarrow[T]{n\\pm i-1} C$ A \\xleftarrow{n+\\mu-1} B \\xrightarrow[T]{n\\pm i-1} C 大括号 $\\overbrace{ 1+2+\\cdots+100 }^{5050}$ \\overbrace{ 1+2+\\cdots+100 }^{5050} 底部大括号 $\\underbrace{ a+b+\\cdots+z }_{26}$ \\underbrace{ a+b+\\cdots+z }_{26} 求和运算 $\\sum_{k=1}^N k^2$ \\sum_{k=1}^N k^2 文本模式下的求和运算 $\\textstyle \\sum_{k=1}^N k^2$ \\textstyle \\sum_{k=1}^N k^2 分式中的求和运算 $\\frac{\\sum_{k=1}^N k^2}{a}$ \\frac{\\sum_{k=1}^N k^2}{a} 分式中的求和运算 $\\frac{\\displaystyle \\sum_{k=1}^N k^2}{a}$ \\frac{\\displaystyle \\sum_{k=1}^N k^2}{a} 分式中的求和运算 $\\frac{\\sum\\limits^{^N}_{k=1} k^2}{a}$ \\frac{\\sum\\limits^{^N}_{k=1} k^2}{a} 乘积运算 $\\prod_{i=1}^N x_i$ \\prod_{i=1}^N x_i 乘积运算 $\\textstyle \\prod_{i=1}^N x_i$ \\textstyle \\prod_{i=1}^N x_i 副乘运算 $\\coprod_{i=1}^N x_i$ \\coprod_{i=1}^N x_i 副乘运算 $\\textstyle \\coprod_{i=1}^N x_i$ \\textstyle \\coprod_{i=1}^N x_i 极限 $\\lim_{n \\to \\infty}x_n$ \\lim_{n \\to \\infty}x_n 极限 $\\textstyle \\lim_{n \\to \\infty}x_n$ \\textstyle \\lim_{n \\to \\infty}x_n 积分 $\\int\\limits_{1}^{3}\\frac{e^3/x}{x^2}\\, dx$ \\int\\limits_{1}^{3}\\frac{e^3/x}{x^2}\\, dx 积分 $\\int_{1}^{3}\\frac{e^3/x}{x^2}\\, dx$ \\int_{1}^{3}\\frac{e^3/x}{x^2}\\, dx 积分 $\\textstyle \\int\\limits_{-N}^{N} e^x dx$ \\textstyle \\int\\limits_{-N}^{N} e^x dx 积分 $\\textstyle \\int_{-N}^{N} e^x dx$ \\textstyle \\int_{-N}^{N} e^x dx 双重积分 $\\iint\\limits_D dx\\,dy$ \\iint\\limits_D dx\\,dy 三重积分 $\\iiint\\limits_E dx\\,dy\\,dz$ \\iiint\\limits_E dx\\,dy\\,dz 路径积分 $\\int_{(x,y)\\in C} x^3\\, dx + 4y^2\\, dy$ \\int_{(x,y)\\in C} x^3\\, dx + 4y^2\\, dy 环路积分 $\\oint_{(x,y)\\in C} x^3\\, dx + 4y^2\\, dy$ \\oint_{(x,y)\\in C} x^3\\, dx + 4y^2\\, dy 交集 $\\bigcap_{i=1}^n E_i$ \\bigcap_{i=1}^n E_i 并集 $\\bigcup_{i=1}^n E_i$ \\bigcup_{i=1}^n E_i 18. 二项式系数 类型 符号 LaTeX 二项式系数 $\\binom{n}{k}$ \\binom{n}{k} 小型二项式系数 $\\tbinom{n}{k}$ \\tbinom{n}{k} 大型二项式系数 $\\dbinom{n}{k}$ \\dbinom{n}{k} ","permalink":"https://www.zzudongxiang.com/posts/latex-math-syntax/","summary":"\u003cdiv\u003e\u003cp\u003e\u003cstrong\u003eMathJax\u003c/strong\u003e是一款运行于 Web 浏览器当中的开源 JavaScript 数学符号渲染引擎，通过它可以方便的在现代 Web 浏览器当中显示数学公式，目前已经能够解析 \u003ccode\u003eLaTex\u003c/code\u003e、\u003ccode\u003eMathML\u003c/code\u003e 等标记语言。\u003cstrong\u003eMathJax\u003c/strong\u003e 项目发源于 2009 年，目前由 NumFOCUS 基金会主持，并且得到了 MathJax 联盟的支持，该联盟是\u003cstrong\u003e美国数学协会\u003c/strong\u003e（AMS）和 \u003cstrong\u003e工业与应用数学协会\u003c/strong\u003e（SIAM）的共同合资企业。\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"images/Snipaste_2023-12-02_22-17-53.png\" alt=\"Snipaste_2023-12-02_22-17-53.png\" /\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eLaTeX\u003c/strong\u003e是一种高质量的排版格式，可以生成复杂的表格与数学公式，是当前电子与数学出版行业的事实标准。本文以 \u003cstrong\u003ePandoc\u003c/strong\u003e作为 LaTex 渲染引擎（一款用于标记语言文档转换的命令行工具），分门别类的总结了撰写数学公式所需要经常使用到的 LaTeX 语法，方便写作相关科技类文章时随手查阅。\u003c/p\u003e\n\u003ch2 id=\"1--希腊字母\"\u003e1. 希腊字母\u003c/h2\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e标准符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003cth align=\"center\"\u003e首字母大写\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003cth align=\"center\"\u003e使用 \u003ccode\u003evar\u003c/code\u003e 前缀\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003cth align=\"center\"\u003e读音\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\alpha$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\alpha\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈælfə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\beta$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\beta\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈbeɪtə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gamma$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gamma\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Gamma$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Gamma\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varGamma$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varGamma\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈɡæmə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\delta$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\delta\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Delta$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Delta\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varDelta$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varDelta\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈdɛltə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\epsilon$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\epsilon\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varepsilon$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varepsilon\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈɛpsɪlɒn/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\zeta$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\zeta\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈzeɪtə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\eta$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\eta\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈeɪtə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e8\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\theta$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\theta\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Theta$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Theta\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\vartheta$、$\\varTheta$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\vartheta\u003c/code\u003e、\u003ccode\u003e\\varTheta\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈθiːtə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e9\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\iota$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\iota\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/aɪˈoʊtə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e10\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\kappa$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\kappa\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varkappa$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varkappa\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈkæpə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e11\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lambda$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lambda\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Lambda$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Lambda\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varLambda$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varLambda\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈlæmdə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e12\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\mu$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\mu\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/mjuː/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e13\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nu$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nu\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/njuː/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e14\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\xi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\xi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Xi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Xi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varXi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varXi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/zaɪ, ksaɪ/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e15\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$o$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003eo\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$O$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003eO\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈɒmɪkrɒn/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e16\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\pi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\pi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Pi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Pi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varpi$、$\\varPi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varpi\u003c/code\u003e、\u003ccode\u003e\\varPi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/paɪ/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e17\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\rho$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\rho\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varrho$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varrho\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/roʊ/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e18\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\sigma$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\sigma\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Sigma$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Sigma\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varsigma$、$\\varSigma$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varsigma\u003c/code\u003e、\u003ccode\u003e\\varSigma\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈsɪɡmə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e19\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\tau$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\tau\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/taʊ, tɔː/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e20\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\upsilon$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\upsilon\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Upsilon$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Upsilon\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varUpsilon$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varUpsilon\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/ˈʌpsɪlɒn/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e21\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\phi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\phi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Phi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Phi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varphi$、$\\varPhi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varphi\u003c/code\u003e、\u003ccode\u003e\\varPhi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/faɪ/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e22\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\chi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\chi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/kaɪ/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e23\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\psi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\psi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Psi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Psi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varPsi$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varPsi\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/psaɪ/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e24\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\omega$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\omega\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Omega$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Omega\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varOmega$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varOmega\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/oʊˈmeɪɡə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e25\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\digamma$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\digamma\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e/daɪ'gæmə/\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"2--二元运算符\"\u003e2. 二元运算符\u003c/h2\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$+$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e+\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e20\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bullet$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bullet\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$-$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e-\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e21\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\oplus$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\oplus\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\times$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\times\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e22\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ominus$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ominus\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\div$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\div\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e23\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\odot$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\odot\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\pm$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\pm\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e24\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\oslash$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\oslash\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\mp$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\mp\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e25\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\otimes$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\otimes\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\triangleleft$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\triangleleft\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e26\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bigcirc$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bigcirc\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e8\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\triangleright$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\triangleright\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e27\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\diamond$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\diamond\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e9\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\cdot$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\cdot\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e28\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\uplus$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\uplus\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e10\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\setminus$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\setminus\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e29\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bigtriangleup$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bigtriangleup\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e11\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\star$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\star\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e30\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bigtriangledown$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bigtriangledown\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e12\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ast$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ast\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e31\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lhd$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lhd\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e13\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\cup$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\cup\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e32\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\rhd$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\rhd\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e14\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\cap$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\cap\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e33\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\unlhd$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\unlhd\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e15\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\sqcup$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\sqcup\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e34\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\unrhd$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\unrhd\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e16\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\sqcap$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\sqcap\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e35\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\amalg$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\amalg\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e17\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\vee$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\vee\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e36\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\wr$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\wr\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e18\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\wedge$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\wedge\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e37\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\dagger$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\dagger\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e19\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\circ$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\circ\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e38\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ddagger$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ddagger\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"3--二元关系符\"\u003e3. 二元关系符\u003c/h2\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$=$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e=\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e49\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gneq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gneq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ne$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ne\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e50\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\geqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\geqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\neq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\neq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e51\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ngeq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ngeq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\equiv$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\equiv\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e52\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ngeqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ngeqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\not\\equiv$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\not\\equiv\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e53\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gneqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gneqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\doteq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\doteq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e54\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gvertneqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gvertneqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\doteqdot$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\doteqdot\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e55\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lessgtr$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lessgtr\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e8\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\overset{\\underset{\\mathrm{def}}{}}{=}$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\overset{\\underset{\\mathrm{def}}{}}{=}\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e56\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lesseqgtr$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lesseqgtr\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e9\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$:=$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e:=\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e57\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lesseqqgtr$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lesseqqgtr\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e10\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\sim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\sim\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e58\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gtrless$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gtrless\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e11\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nsim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nsim\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e59\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gtreqless$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gtreqless\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e12\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\backsim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\backsim\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e60\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gtreqqless$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gtreqqless\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e13\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\thicksim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\thicksim\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e61\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leqslant$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leqslant\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e14\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\simeq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\simeq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e62\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nleqslant$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nleqslant\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e15\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\backsimeq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\backsimeq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e63\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\eqslantless$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\eqslantless\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e16\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\eqsim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\eqsim\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e64\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\geqslant$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\geqslant\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e17\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\cong$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\cong\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e65\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ngeqslant$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ngeqslant\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e18\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ncong$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ncong\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e66\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\eqslantgtr$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\eqslantgtr\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e19\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\approx$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\approx\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e67\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lesssim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lesssim\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e20\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\thickapprox$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\thickapprox\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e68\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lnsim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lnsim\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e21\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\approxeq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\approxeq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e69\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lessapprox$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lessapprox\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e22\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\asymp$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\asymp\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e70\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lnapprox$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lnapprox\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e23\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\propto$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\propto\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e71\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gtrsim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gtrsim\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e24\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varpropto$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varpropto\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e72\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gnsim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gnsim\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e25\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\u0026lt;$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\u0026lt;\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e73\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gtrapprox$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gtrapprox\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e26\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nless$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nless\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e74\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gnapprox$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gnapprox\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e27\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ll$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ll\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e75\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\prec$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\prec\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e28\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\not\\ll$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\not\\ll\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e76\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nprec$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nprec\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e29\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lll$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lll\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e77\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\preceq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\preceq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e30\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\not\\lll$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\not\\lll\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e78\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\npreceq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\npreceq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e31\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lessdot$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lessdot\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e79\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\precneqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\precneqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e32\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\u0026gt;$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\u0026gt;\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e80\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\succ$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\succ\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e33\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ngtr$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ngtr\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e81\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nsucc$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nsucc\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e34\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gg$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gg\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e82\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\succeq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\succeq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e35\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\not\\gg$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\not\\gg\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e83\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nsucceq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nsucceq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e36\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ggg$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ggg\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e84\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\succneqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\succneqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e37\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\not\\ggg$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\not\\ggg\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e85\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\preccurlyeq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\preccurlyeq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e38\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gtrdot$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gtrdot\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e86\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\curlyeqprec$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\curlyeqprec\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e39\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\le$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\le\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e87\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\succcurlyeq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\succcurlyeq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e40\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e88\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\curlyeqsucc$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\curlyeqsucc\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e41\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lneq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lneq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e89\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\precsim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\precsim\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e42\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leqq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e90\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\precnsim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\precnsim\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e43\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nleq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nleq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e91\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\precapprox$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\precapprox\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e44\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nleqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nleqq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e92\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\precnapprox$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\precnapprox\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e45\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lneqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lneqq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e93\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\succsim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\succsim\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e46\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lvertneqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lvertneqq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e94\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\succnsim$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\succnsim\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e47\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ge$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ge\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e95\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\succapprox$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\succapprox\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e48\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\geq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\geq\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e96\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\succnapprox$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\succnapprox\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"4--逻辑符号\"\u003e4. 逻辑符号\u003c/h2\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\forall$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\forall\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e20\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\neg$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\neg\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\exists$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\exists\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e21\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\not\\operatorname{R}$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\not\\operatorname{R}\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nexists$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nexists\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e22\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bot$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bot\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\therefore$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\therefore\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e23\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\top$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\top\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\because$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\because\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e24\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\vdash$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\vdash\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\And$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\And\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e25\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\dashv$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\dashv\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lor$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lor\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e26\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\vDash$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\vDash\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e8\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\vee$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\vee\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e27\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Vdash$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Vdash\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e9\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\curlyvee$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\curlyvee\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e28\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\models$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\models\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e10\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bigvee$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bigvee\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e29\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Vvdash$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Vvdash\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e11\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\land$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\land\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e30\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nvdash$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nvdash\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e12\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\wedge$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\wedge\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e31\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nVdash$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nVdash\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e13\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\curlywedge$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\curlywedge\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e32\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nvDash$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nvDash\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e14\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bigwedge$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bigwedge\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e33\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nVDash$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nVDash\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e15\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bar{q}$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bar{q}\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e34\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ulcorner$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ulcorner\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e16\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bar{abc}$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bar{abc}\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e35\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\urcorner$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\urcorner\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e17\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\overline{q}$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\overline{q}\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e36\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\llcorner$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\llcorner\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e18\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\overline{abc}$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\overline{abc}\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e37\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lrcorner$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lrcorner\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e19\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\lnot$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\lnot\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"5--集合符号\"\u003e5. 集合符号\u003c/h2\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\{ \\}$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\{ \\}\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e23\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\sqsubset$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\sqsubset\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\emptyset$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\emptyset\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e24\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\supset$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\supset\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varnothing$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varnothing\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e25\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Supset$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Supset\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\in$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\in\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e26\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\sqsupset$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\sqsupset\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\notin$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\notin\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e27\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\subseteq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\subseteq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ni$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ni\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e28\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nsubseteq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nsubseteq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\cap$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\cap\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e29\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\subsetneq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\subsetneq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e8\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Cap$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Cap\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e30\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varsubsetneq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varsubsetneq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e9\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\sqcap$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\sqcap\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e31\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\sqsubseteq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\sqsubseteq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e10\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bigcap$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bigcap\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e32\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\supseteq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\supseteq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e11\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\cup$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\cup\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e33\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nsupseteq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nsupseteq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e12\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Cup$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Cup\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e34\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\supsetneq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\supsetneq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e13\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\sqcup$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\sqcup\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e35\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varsupsetneq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varsupsetneq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e14\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bigcup$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bigcup\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e36\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\sqsupseteq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\sqsupseteq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e15\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bigsqcup$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bigsqcup\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e37\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\subseteqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\subseteqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e16\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\uplus$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\uplus\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e38\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nsubseteqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nsubseteqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e17\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\biguplus$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\biguplus\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e39\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\subsetneqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\subsetneqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e18\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\setminus$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\setminus\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e40\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varsubsetneqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varsubsetneqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e19\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\smallsetminus$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\smallsetminus\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e41\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\supseteqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\supseteqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e20\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\times$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\times\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e42\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nsupseteqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nsupseteqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e21\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\subset$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\subset\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e43\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\supsetneqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\supsetneqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e22\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Subset$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Subset\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e44\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\varsupsetneqq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\varsupsetneqq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"6--箭头符号\"\u003e6. 箭头符号\u003c/h2\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Rrightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Rrightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e36\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\longmapsto$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\longmapsto\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Lleftarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Lleftarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e37\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\rightharpoonup$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\rightharpoonup\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Rightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Rightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e38\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\rightharpoondown$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\rightharpoondown\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nRightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nRightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e39\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leftharpoonup$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leftharpoonup\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Longrightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Longrightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e40\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leftharpoondown$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leftharpoondown\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\implies$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\implies\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e41\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\upharpoonleft$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\upharpoonleft\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Leftarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Leftarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e42\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\upharpoonright$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\upharpoonright\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e8\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nLeftarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nLeftarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e43\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\downharpoonleft$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\downharpoonleft\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e9\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Longleftarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Longleftarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e44\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\downharpoonright$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\downharpoonright\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e10\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Leftrightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Leftrightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e45\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\rightleftharpoons$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\rightleftharpoons\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e11\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nLeftrightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nLeftrightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e46\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leftrightharpoons$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leftrightharpoons\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e12\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Longleftrightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Longleftrightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e47\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\curvearrowleft$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\curvearrowleft\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e13\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\iff$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\iff\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e48\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\circlearrowleft$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\circlearrowleft\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e14\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Uparrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Uparrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e49\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Lsh$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Lsh\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e15\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Downarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Downarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e50\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\upuparrows$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\upuparrows\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e16\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Updownarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Updownarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e51\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\rightrightarrows$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\rightrightarrows\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e17\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\rightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\rightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e52\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\rightleftarrows$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\rightleftarrows\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e18\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\to$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\to\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e53\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\rightarrowtail$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\rightarrowtail\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e19\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nrightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nrightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e54\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\looparrowright$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\looparrowright\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e20\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\longrightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\longrightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e55\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\curvearrowright$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\curvearrowright\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e21\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leftarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leftarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e56\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\circlearrowright$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\circlearrowright\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e22\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\gets$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\gets\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e57\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Rsh$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Rsh\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e23\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nleftarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nleftarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e58\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\downdownarrows$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\downdownarrows\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e24\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\longleftarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\longleftarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e59\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leftleftarrows$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leftleftarrows\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e25\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leftrightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leftrightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e60\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leftrightarrows$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leftrightarrows\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e26\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nleftrightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nleftrightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e61\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leftarrowtail$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leftarrowtail\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e27\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\longleftrightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\longleftrightarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e62\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\looparrowleft$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\looparrowleft\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e28\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\uparrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\uparrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e63\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\hookrightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\hookrightarrow\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e29\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\downarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\downarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e64\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\hookleftarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\hookleftarrow\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e30\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\updownarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\updownarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e65\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\multimap$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\multimap\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e31\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nearrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nearrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e66\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leftrightsquigarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leftrightsquigarrow\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e32\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\swarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\swarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e67\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\rightsquigarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\rightsquigarrow\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e33\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\nwarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\nwarrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e68\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\twoheadrightarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\twoheadrightarrow\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e34\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\searrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\searrow\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e69\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\twoheadleftarrow$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\twoheadleftarrow\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e35\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\mapsto$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\mapsto\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"7--特殊符号\"\u003e7. 特殊符号\u003c/h2\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003cth align=\"center\"\u003e序号\u003c/th\u003e\n\u003cth align=\"center\"\u003e符号\u003c/th\u003e\n\u003cth align=\"center\"\u003eLaTeX\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\infty$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\infty\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e33\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\flat$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\flat\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\aleph$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\aleph\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e34\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\natural$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\natural\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\complement$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\complement\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e35\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\sharp$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\sharp\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\backepsilon$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\backepsilon\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e36\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\diagup$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\diagup\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\eth$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\eth\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e37\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\diagdown$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\diagdown\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Finv$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Finv\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e38\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\centerdot$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\centerdot\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\hbar$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\hbar\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e39\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ltimes$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ltimes\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e8\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Im$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Im\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e40\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\rtimes$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\rtimes\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e9\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\imath$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\imath\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e41\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\leftthreetimes$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\leftthreetimes\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e10\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\jmath$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\jmath\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e42\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\rightthreetimes$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\rightthreetimes\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e11\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Bbbk$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Bbbk\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e43\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\eqcirc$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\eqcirc\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e12\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ell$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ell\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e44\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\circeq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\circeq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e13\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\mho$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\mho\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e45\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\triangleq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\triangleq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e14\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\wp$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\wp\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e46\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\bumpeq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\bumpeq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e15\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Re$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Re\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e47\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Bumpeq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Bumpeq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e16\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\circledS$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\circledS\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e48\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\doteqdot$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\doteqdot\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e17\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\amalg$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\amalg\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e49\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\risingdotseq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\risingdotseq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e18\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\%$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\%\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e50\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\fallingdotseq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\fallingdotseq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e19\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\dagger$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\dagger\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e51\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\intercal$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\intercal\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e20\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ddagger$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ddagger\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e52\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\barwedge$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\barwedge\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e21\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ldots$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ldots\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e53\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\veebar$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\veebar\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e22\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\cdots$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\cdots\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e54\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\doublebarwedge$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\doublebarwedge\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e23\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\smile$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\smile\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e55\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\between$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\between\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e24\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\frown$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\frown\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e56\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\pitchfork$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\pitchfork\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e25\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\wr$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\wr\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e57\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\vartriangleleft$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\vartriangleleft\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e26\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\triangleleft$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\triangleleft\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e58\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ntriangleleft$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ntriangleleft\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e27\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\triangleright$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\triangleright\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e59\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\vartriangleright$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\vartriangleright\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e28\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\diamondsuit$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\diamondsuit\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e60\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ntriangleright$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ntriangleright\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e29\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\heartsuit$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\heartsuit\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e61\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\trianglelefteq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\trianglelefteq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e30\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\clubsuit$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\clubsuit\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e62\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ntrianglelefteq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ntrianglelefteq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e31\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\spadesuit$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\spadesuit\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e63\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\trianglerighteq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\trianglerighteq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e32\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\Game$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\Game\u003c/code\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cstrong\u003e64\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e$\\ntrianglerighteq$\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ccode\u003e\\ntrianglerighteq\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"8--分数\"\u003e8. 分数\u003c/h2\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"left\"\u003e类型\u003c/th\u003e\n\u003cth align=\"left\"\u003e符号\u003c/th\u003e\n\u003cth align=\"left\"\u003eLaTeX\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e\u003cstrong\u003e分数\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"left\"\u003e$\\frac{2}{4}x=0.5x or {2 \\over 4}x=0.5x$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\frac{2}{4}x=0.5x or {2 \\over 4}x=0.5x\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e\u003cstrong\u003e小型分数\u003c/strong\u003e\u003c/td\u003e\n\u003ctd align=\"left\"\u003e$\\tfrac{2}{4}x = 0.5x$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\tfrac{2}{4}x = 0.5x\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e\u003cstrong\u003e大型分数\u003c/strong\u003e （嵌套）\u003c/td\u003e\n\u003ctd align=\"left\"\u003e$\\cfrac{2}{c + \\cfrac{2}{d + \\cfrac{2}{4}}} = a$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\cfrac{2}{c + \\cfrac{2}{d + \\cfrac{2}{4}}} = a\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"9--数值函数\"\u003e9. 数值函数\u003c/h2\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"left\"\u003e符号\u003c/th\u003e\n\u003cth align=\"left\"\u003eLaTeX\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e$\\exp_a b = a^b, \\exp b = e^b, 10^m$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\exp_a b = a^b, \\exp b = e^b, 10^m\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e$\\ln c, \\lg d = \\log e, \\log_{10} f$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\ln c, \\lg d = \\log e, \\log_{10} f\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e$\\sin a, \\cos b, \\tan c, \\cot d, \\sec e, \\csc f$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\sin a, \\cos b, \\tan c, \\cot d, \\sec e, \\csc f\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e$\\arcsin a, \\arccos b, \\arctan c$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\arcsin a, \\arccos b, \\arctan c\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e$\\operatorname{arccot} d, \\operatorname{arcsec} e, \\operatorname{arccsc} f$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\operatorname{arccot} d, \\operatorname{arcsec} e, \\operatorname{arccsc} f\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e$\\sinh a, \\cosh b, \\tanh c, \\coth d$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\sinh a, \\cosh b, \\tanh c, \\coth d\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e$\\operatorname{sh}k, \\operatorname{ch}l, \\operatorname{th}m, \\operatorname{coth}n$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\operatorname{sh}k, \\operatorname{ch}l, \\operatorname{th}m, \\operatorname{coth}n\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e$\\operatorname{argsh}o, \\operatorname{argch}p, \\operatorname{argth}q$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\operatorname{argsh}o, \\operatorname{argch}p, \\operatorname{argth}q\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e$\\operatorname{sgn}r, \\left\\vert s \\right\\vert$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\operatorname{sgn}r, \\left\\vert s \\right\\vert\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"left\"\u003e$\\min(x,y), \\max(x,y)$\u003c/td\u003e\n\u003ctd align=\"left\"\u003e\u003ccode\u003e\\min(x,y), \\max(x,y)\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e如果需要使用特殊的函数符号，那么可以采用 \u003ccode\u003e\\operatorname{}\u003c/code\u003e 命令进行自定义：\u003c/p\u003e","title":"通用LaTex数学公式语法手册"}]