[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-lartpang--PyTorchTricks":3,"tool-lartpang--PyTorchTricks":64},[4,17,27,35,43,56],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":16},3808,"stable-diffusion-webui","AUTOMATIC1111\u002Fstable-diffusion-webui","stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面，旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点，将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。\n\n无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师，还是想要深入探索模型潜力的开发者与研究人员，都能从中获益。其核心亮点在于极高的功能丰富度：不仅支持文生图、图生图、局部重绘（Inpainting）和外绘（Outpainting）等基础模式，还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外，它内置了 GFPGAN 和 CodeFormer 等人脸修复工具，支持多种神经网络放大算法，并允许用户通过插件系统无限扩展能力。即使是显存有限的设备，stable-diffusion-webui 也提供了相应的优化选项，让高质量的 AI 艺术创作变得触手可及。",162132,3,"2026-04-05T11:01:52",[13,14,15],"开发框架","图像","Agent","ready",{"id":18,"name":19,"github_repo":20,"description_zh":21,"stars":22,"difficulty_score":23,"last_commit_at":24,"category_tags":25,"status":16},1381,"everything-claude-code","affaan-m\u002Feverything-claude-code","everything-claude-code 是一套专为 AI 编程助手（如 Claude Code、Codex、Cursor 等）打造的高性能优化系统。它不仅仅是一组配置文件，而是一个经过长期实战打磨的完整框架，旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。\n\n通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能，everything-claude-code 能显著提升 AI 在复杂任务中的表现，帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略，使得模型响应更快、成本更低，同时有效防御潜在的攻击向量。\n\n这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库，还是需要 AI 协助进行安全审计与自动化测试，everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目，它融合了多语言支持与丰富的实战钩子（hooks），让 AI 真正成长为懂上",138956,2,"2026-04-05T11:33:21",[13,15,26],"语言模型",{"id":28,"name":29,"github_repo":30,"description_zh":31,"stars":32,"difficulty_score":23,"last_commit_at":33,"category_tags":34,"status":16},2271,"ComfyUI","Comfy-Org\u002FComfyUI","ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎，专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式，采用直观的节点式流程图界面，让用户通过连接不同的功能模块即可构建个性化的生成管线。\n\n这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景，也能自由组合模型、调整参数并实时预览效果，轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性，不仅支持 Windows、macOS 和 Linux 全平台，还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构，并率先支持 SDXL、Flux、SD3 等前沿模型。\n\n无论是希望深入探索算法潜力的研究人员和开发者，还是追求极致创作自由度的设计师与资深 AI 绘画爱好者，ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",107662,"2026-04-03T11:11:01",[13,14,15],{"id":36,"name":37,"github_repo":38,"description_zh":39,"stars":40,"difficulty_score":23,"last_commit_at":41,"category_tags":42,"status":16},3704,"NextChat","ChatGPTNextWeb\u002FNextChat","NextChat 是一款轻量且极速的 AI 助手，旨在为用户提供流畅、跨平台的大模型交互体验。它完美解决了用户在多设备间切换时难以保持对话连续性，以及面对众多 AI 模型不知如何统一管理的痛点。无论是日常办公、学习辅助还是创意激发，NextChat 都能让用户随时随地通过网页、iOS、Android、Windows、MacOS 或 Linux 端无缝接入智能服务。\n\n这款工具非常适合普通用户、学生、职场人士以及需要私有化部署的企业团队使用。对于开发者而言，它也提供了便捷的自托管方案，支持一键部署到 Vercel 或 Zeabur 等平台。\n\nNextChat 的核心亮点在于其广泛的模型兼容性，原生支持 Claude、DeepSeek、GPT-4 及 Gemini Pro 等主流大模型，让用户在一个界面即可自由切换不同 AI 能力。此外，它还率先支持 MCP（Model Context Protocol）协议，增强了上下文处理能力。针对企业用户，NextChat 提供专业版解决方案，具备品牌定制、细粒度权限控制、内部知识库整合及安全审计等功能，满足公司对数据隐私和个性化管理的高标准要求。",87618,"2026-04-05T07:20:52",[13,26],{"id":44,"name":45,"github_repo":46,"description_zh":47,"stars":48,"difficulty_score":23,"last_commit_at":49,"category_tags":50,"status":16},2268,"ML-For-Beginners","microsoft\u002FML-For-Beginners","ML-For-Beginners 是由微软推出的一套系统化机器学习入门课程，旨在帮助零基础用户轻松掌握经典机器学习知识。这套课程将学习路径规划为 12 周，包含 26 节精炼课程和 52 道配套测验，内容涵盖从基础概念到实际应用的完整流程，有效解决了初学者面对庞大知识体系时无从下手、缺乏结构化指导的痛点。\n\n无论是希望转型的开发者、需要补充算法背景的研究人员，还是对人工智能充满好奇的普通爱好者，都能从中受益。课程不仅提供了清晰的理论讲解，还强调动手实践，让用户在循序渐进中建立扎实的技能基础。其独特的亮点在于强大的多语言支持，通过自动化机制提供了包括简体中文在内的 50 多种语言版本，极大地降低了全球不同背景用户的学习门槛。此外，项目采用开源协作模式，社区活跃且内容持续更新，确保学习者能获取前沿且准确的技术资讯。如果你正寻找一条清晰、友好且专业的机器学习入门之路，ML-For-Beginners 将是理想的起点。",84991,"2026-04-05T10:45:23",[14,51,52,53,15,54,26,13,55],"数据工具","视频","插件","其他","音频",{"id":57,"name":58,"github_repo":59,"description_zh":60,"stars":61,"difficulty_score":10,"last_commit_at":62,"category_tags":63,"status":16},3128,"ragflow","infiniflow\u002Fragflow","RAGFlow 是一款领先的开源检索增强生成（RAG）引擎，旨在为大语言模型构建更精准、可靠的上下文层。它巧妙地将前沿的 RAG 技术与智能体（Agent）能力相结合，不仅支持从各类文档中高效提取知识，还能让模型基于这些知识进行逻辑推理和任务执行。\n\n在大模型应用中，幻觉问题和知识滞后是常见痛点。RAGFlow 通过深度解析复杂文档结构（如表格、图表及混合排版），显著提升了信息检索的准确度，从而有效减少模型“胡编乱造”的现象，确保回答既有据可依又具备时效性。其内置的智能体机制更进一步，使系统不仅能回答问题，还能自主规划步骤解决复杂问题。\n\n这款工具特别适合开发者、企业技术团队以及 AI 研究人员使用。无论是希望快速搭建私有知识库问答系统，还是致力于探索大模型在垂直领域落地的创新者，都能从中受益。RAGFlow 提供了可视化的工作流编排界面和灵活的 API 接口，既降低了非算法背景用户的上手门槛，也满足了专业开发者对系统深度定制的需求。作为基于 Apache 2.0 协议开源的项目，它正成为连接通用大模型与行业专有知识之间的重要桥梁。",77062,"2026-04-04T04:44:48",[15,14,13,26,54],{"id":65,"github_repo":66,"name":67,"description_en":68,"description_zh":69,"ai_summary_zh":69,"readme_en":70,"readme_zh":71,"quickstart_zh":72,"use_case_zh":73,"hero_image_url":74,"owner_login":75,"owner_name":76,"owner_avatar_url":77,"owner_bio":78,"owner_company":79,"owner_location":80,"owner_email":81,"owner_twitter":81,"owner_website":82,"owner_url":83,"languages":81,"stars":84,"forks":85,"last_commit_at":86,"license":81,"difficulty_score":87,"env_os":88,"env_gpu":89,"env_ram":90,"env_deps":91,"category_tags":103,"github_topics":104,"view_count":23,"oss_zip_url":81,"oss_zip_packed_at":81,"status":16,"created_at":109,"updated_at":110,"faqs":111,"releases":112},2597,"lartpang\u002FPyTorchTricks","PyTorchTricks","Some tricks of pytorch... :star:","PyTorchTricks 是一个专注于提升 PyTorch 深度学习项目效率的开源技巧合集。它主要解决了模型训练与推理过程中常见的性能瓶颈问题，特别是数据加载缓慢、显存占用过高以及训练速度不理想等痛点。\n\n该资源非常适合广大 AI 开发者、算法研究人员及深度学习爱好者使用。无论是需要处理千万级大规模数据集的工程师，还是希望在有限硬件资源下优化实验流程的研究者，都能从中获得实用的解决方案。\n\n其核心亮点在于系统性地整理了从数据预处理到模型训练的全链路加速策略。在数据层面，涵盖了利用 DALI 进行 GPU 加速预处理、采用 LMDB 或 Tar 格式整合小文件以减少 IO 开销、以及内存缓存等高效读取方案；在训练层面，深入介绍了混合精度训练（FP16）、梯度累积以支持更大 Batch Size、以及卷积层与 BN 层融合等前沿技巧。此外，项目还持续更新关于模型量化压缩的最新实践。PyTorchTricks 不仅罗列方法，更提供了丰富的代码示例与权威参考链接，帮助用户快速落地优化措施，显著提升开发效率。","# Some Tricks of PyTorch\n\n## changelog\n\n* 2019 年 11 月 29 日: 更新一些模型设计技巧和推理加速的内容, 补充了下 apex 的一个介绍链接, ~~另外删了 tfrecord, pytorch 能用么? 这个我记得是不能, 所以删掉了~~(表示删掉:\u003C)\n* 2019 年 11 月 30 日: 补充 MAC 的含义, 补充 ShuffleNetV2 的论文链接\n* 2019 年 12 月 02 日: 之前说的 pytorch 不能用 tfrecord, 今天看到\u003Chttps:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F358632497>下的一个回答, 涨姿势了\n* 2019 年 12 月 23 日: 补充几篇关于模型压缩量化的科普性文章\n* 2020 年 2 月 7 日: 从文章中摘录了一点注意事项, 补充在了 [代码层面](#代码层面) 小节\n* 2020 年 4 月 30 日:\n  * 添加了一个 github 的文档备份\n  * 补充了卷积层和 BN 层融合的介绍的链接\n  * 另外这里说明下, 对于之前参考的很多朋友的文章和回答, 没有把链接和对应的内容提要关联在一起, 估计会导致一些朋友阅读时相关的内容时的提问, 无法问到原作者, 这里深感抱歉.\n  * 调整部分内容, 将内容尽量与参考链接相对应\n* 2020 年 5 月 18 日: 补充一些关于 PyTorch 节省显存的技巧. 同时简单调整格式. 另外发现一个之前的错误: `non_blocking=False` 的建议应该是 `non_blocking=True` .\n* 2021 年 01 月 06 日：调整下关于读取图片数据的一些介绍.\n* 2021 年 01 月 13 日：补充了一条推理加速的策略. 我觉得我应该先更新 github 的文档，知乎答案的更新有点麻烦，也没法比较更改信息，就很费劲。\n* 2022 年 6 月 26 日：重新调整了下格式和内容安排，同时补充了更多的参考资料和一些最新发现的有效内容。\n* 2024 年 6 月 20 日：简单调整格式，补充了基于 `tar` 格式和 `IterableDataset` 的一种加速数据读取的思路。\n\n## PyTorch 提速\n\n> [!note]\n> 原始文档:\u003Chttps:\u002F\u002Fwww.yuque.com\u002Flart\u002Fugkv9f\u002Fugysgn>\n>\n> 声明: 大部分内容来自知乎和其他博客的分享, 这里只作为一个收集罗列. 欢迎给出更多建议.\n\n知乎回答 (欢迎点赞哦):\n\n* [pytorch dataloader 数据加载占用了大部分时间, 各位大佬都是怎么解决的? - 人民艺术家的回答 - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F307282137\u002Fanswer\u002F907835663)\n* [使用 pytorch 时, 训练集数据太多达到上千万张, Dataloader 加载很慢怎么办? - 人民艺术家的回答 - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F356829360\u002Fanswer\u002F907832358)\n\n### 预处理提速\n\n* 尽量减少每次读取数据时的预处理操作, 可以考虑把一些固定的操作, 例如 `resize` , 事先处理好保存下来, 训练的时候直接拿来用。\n* 将预处理搬到 GPU 上加速。\n  * Linux 可以使用 [`NVIDIA\u002FDALI`](https:\u002F\u002Fgithub.com\u002FNVIDIA\u002FDALI)。\n  * 使用基于 Tensor 的图像处理操作。\n\n### IO 提速\n\n* mmcv 对数据的读取提供了比较高效且全面的支持：[OpenMMLab：MMCV 核心组件分析(三): FileClient](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F339190576)\n\n#### 使用更快的图片处理\n\n* `opencv` 一般要比 `PIL` 要快 。\n  * 请注意，`PIL` 的惰性加载的策略使得其看上去 `open` 要比 `opencv` 的 `imread` 要快，但是实际上那并没有完全加载数据。可以对 `open` 返回的对象调用其 `load()` 方法，从而手动加载数据，这时的速度才是合理的。\n* 对于 `jpeg` 读取, 可以尝试 `jpeg4py`。\n* 存 `bmp` 图 (降低解码时间)。\n* 关于不同图像处理库速度的讨论：[Python 的各种 imread 函数在实现方式和读取速度上有何区别？ - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F48762352)\n\n#### 整合数据为单个连续文件 (降低读取次数)\n\n对于大规模的小文件读取，可以保存为一个可以连续读取的连续文件格式。[可以选择考虑 `TFRecord (Tensorflow)` , `recordIO`, `hdf5`, `pth`, `n5`, `lmdb`等](https:\u002F\u002Fgithub.com\u002FLyken17\u002FEfficient-PyTorch#data-loader)。\n\n* `TFRecord` ：\u003Chttps:\u002F\u002Fgithub.com\u002Fvahidk\u002Ftfrecord>\n* `lmdb` 数据库：\n  * \u003Chttps:\u002F\u002Fgithub.com\u002FFangyh09\u002FImage2LMDB>\n  * \u003Chttps:\u002F\u002Fblog.csdn.net\u002FP_LarT\u002Farticle\u002Fdetails\u002F103208405>\n  * \u003Chttps:\u002F\u002Fgithub.com\u002Flartpang\u002FPySODToolBox\u002Fblob\u002Fmaster\u002FForBigDataset\u002FImageFolder2LMDB.py>\n* 基于 [`Tar`文件和`IterableDataset`的实现](https:\u002F\u002Fgithub.com\u002Fvahidk\u002FEffectivePyTorch?tab=readme-ov-file#building-efficient-custom-data-loaders)\n\n#### 预读取数据\n\n预读取下一次迭代需要的数据。使用案例：\n\n* [如何给你 PyTorch 里的 Dataloader 打鸡血 - MKFMIKU 的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F66145913)\n* [给 pytorch 读取数据加速 - 体 hi 的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F72956595)\n\n#### 借助内存\n\n* 直接载到内存里面。\n  * 将图片读取后存到一个固定的容器对象中。\n    * YoloV5 中的 [`--cache`](https:\u002F\u002Fgithub.com\u002Fultralytics\u002Fyolov5\u002Fblob\u002F19f33cbae29ac2127dd877b52e228c178dda6086\u002Futils\u002Fdataloaders.py#L521-L534)。\n* 把内存映射成磁盘。\n\n#### 借助固态\n\n机械硬盘换成 NVME 固态。参考自 [如何给你 PyTorch 里的 Dataloader 打鸡血 - MKFMIKU 的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F66145913)\n\n### 训练策略\n\n#### 低精度训练\n\n在训练中使用低精度 ( `FP16` 甚至 `INT8` 、二值网络、三值网络) 表示取代原有精度 ( `FP32` ) 表示。\n\n可以节约一定的显存并提速, 但是要小心一些不安全的操作如 mean 和 sum。\n\n* 混合精度训练的介绍文章：\n  * [由浅入深的混合精度训练教程](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002F6FCumAWa8fZ1r7xwIRC9ow)\n* [`NVIDIA\u002FApex`](https:\u002F\u002Fgithub.com\u002Fnvidia\u002Fapex) 提供的混合精度支持。\n  * [PyTorch 必备神器 | 唯快不破：基于 Apex 的混合精度加速](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002FHQnI8rzPvZN6Q_5c8d1nVQ)\n  * [Pytorch 安装 APEX 疑难杂症解决方案 - 陈瀚可的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F80386137)\n* [PyTorch1.6 开始提供的`torch.cuda.amp`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Famp_examples.html) 以支持混合精度。\n\n#### 更大的 batch\n\n更大的 batch 在固定的 epoch 的情况下往往会带来更短的训练时间。但是大的 batch 面临着超参数的设置、显存占用问题等诸多考量，这又是另一个备受关注的领域了。\n\n* 超参数设置\n  * Accurate, large minibatch SGD: training imagenet in 1 hour，[论文](https:\u002F\u002Farxiv.org\u002Fabs\u002F1706.02677)\n* 优化显存占用\n  * [Gradient Accumulation](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Famp_examples.html#gradient-accumulation)\n  * [Gradient Checkpointing](https:\u002F\u002Fpytorch.org\u002Fdocs\u002F1.11\u002Fcheckpoint.html#torch-utils-checkpoint)\n    * Training deep nets with sublinear memory cost，[论文](https:\u002F\u002Farxiv.org\u002Fabs\u002F1604.06174)\n  * In-Place Operation\n    * In-Place Activated BatchNorm for Memory-Optimized Training of DNNs，[论文](https:\u002F\u002Farxiv.org\u002Fabs\u002F1712.02616)，[代码](https:\u002F\u002Fgithub.com\u002Fmapillary\u002Finplace_abn)\n\n### 代码层面\n\n#### 库设置\n\n* 在训练循环之前设置 `torch.backends.cudnn.benchmark = True` 可以加速计算。由于计算不同内核大小卷积的 cuDNN 算法的性能不同，自动调优器可以运行一个基准来找到最佳算法。当你的输入大小不经常改变时，建议开启这个设置。如果输入大小经常改变，那么自动调优器就需要太频繁地进行基准测试，这可能会损害性能。它可以将向前和向后传播速度提高 1.27x 到 1.70x。\n* 使用页面锁定内存，即在 DataLoader 中设定 [`pin_memory=True`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fdata.html#memory-pinning)。\n* 合适的 `num_worker`，细节讨论可见 [Pytorch 提速指南 - 云梦的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F39752167)。\n* [optimizer.zero_grad(set_to_none=False](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fgenerated\u002Ftorch.optim.Optimizer.zero_grad.html#torch-optim-optimizer-zero-grad) 这里可以通过设置 `set_to_none=True` 来降低的内存占用，并且可以适度提高性能。但是这也会改变某些行为，具体可见文档。通过 `model.zero_grad()` 或 `optimizer.zero_grad()` 将对所有参数执行 `memset`，并通过读写操作更新梯度。但是，将梯度设置为 `None` 将不会执行 `memset`，并且将使用“只写”操作更新梯度。因此，设置梯度为 `None` 更快。\n* 反向传播期间设定使用 `eval` 模式并使用 `torch.no_grad` 关闭梯度计算。\n* 可以考虑使用 [channels_last](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Ftensor_attributes.html#torch-memory-format) 的内存格式。\n* [用`DistributedDataParallel`代替`DataParallel`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Fcuda.html#use-nn-parallel-distributeddataparallel-instead-of-multiprocessing-or-nn-dataparallel)。对于多 GPU 来说，即使只有单个节点，也总是优先使用 `DistributedDataParallel` 而不是 `DataParallel` ，因为 `DistributedDataParallel` 应用于多进程，并为每个 GPU 创建一个进程，从而绕过 Python 全局解释器锁 (GIL) 并提高速度。\n\n#### 模型\n\n* 不要初始化任何用不到的变量，因为 PyTorch 的初始化和 `forward` 是分开的，他不会因为你不去使用，而不去初始化。\n* [`@torch.jit.script`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fgenerated\u002Ftorch.jit.script.html#torch.jit.script)，使用 PyTroch JIT 将逐点运算融合到单个 CUDA kernel 上。PyTorch 优化了维度很大的张量的运算操作。在 PyTorch 中对小张量进行太多的运算操作是非常低效的。所以有可能的话，将计算操作都重写为批次（batch）的形式，可以减少消耗和提高性能。而如果没办法自己手动实现批次的运算操作，那么可以采用 TorchScript 来提升代码的性能。TorchScript 是一个 Python 函数的子集，但经过了 PyTorch 的验证，PyTorch 可以通过其 just in time(jtt) 编译器来自动优化 TorchScript 代码，提高性能。但更好的做法还是手动实现批次的运算操作。\n* 在使用混合精度的 FP16 时，对于所有不同架构设计，设置尺寸为 8 的倍数。\n* BN 之前的卷积层可以去掉 bias。因为在数学上，bias 可以通过 BN 的均值减法来抵消。我们可以节省模型参数、运行时的内存。\n\n#### 数据\n\n* 将 batch size 设置为 8 的倍数，最大化 GPU 内存的使用。\n* GPU 上尽可能执行 NumPy 风格的操作。\n* 使用 `del` 释放内存占用。\n* 避免不同设备之间不必要的数据传输。\n* 创建张量的时候，直接指定设备，而不要创建后再传输到目标设备上。\n* 使用 [`torch.from_numpy(ndarray)`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fgenerated\u002Ftorch.from_numpy.html#torch-from-numpy) 或者 [`torch.as_tensor(data, dtype=None, device=None)`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fgenerated\u002Ftorch.as_tensor.html#torch-as-tensor)，这可以通过共享内存而避免重新申请空间，具体使用细节和注意事项可参考对应文档。如果源设备和目标设备都是 CPU，`torch.from_numpy` 和 `torch.as_tensor` 不会拷贝数据。如果源数据是 NumPy 数组，使用 `torch.from_numpy` 更快。如果源数据是一个具有相同数据类型和设备类型的张量，那么 `torch.as_tensor` 可以避免拷贝数据，这里的数据可以是 Python 的 list， tuple，或者张量。\n* 使用非阻塞传输，即设定 `non_blocking=True`。这会在可能的情况下尝试异步转换，例如，将页面锁定内存中的 CPU 张量转换为 CUDA 张量。\n\n### 对优化器的优化\n\n* 将模型参数存放到一块连续的内存中，从而减少 `optimizer.step()` 的时间。\n  * [`contiguous_pytorch_params`](https:\u002F\u002Fgithub.com\u002FPhilJd\u002Fcontiguous_pytorch_params)\n* 使用 APEX 中的 [fused building blocks](https:\u002F\u002Fnvidia.github.io\u002Fapex\u002Foptimizers.html)\n\n### 模型设计\n\n#### CNN\n\n* ShuffleNetV2，[论文](https:\u002F\u002Farxiv.org\u002Fpdf\u002F1807.11164.pdf)。\n  * 卷积层输入输出通道一致: 卷积层的输入和输出特征通道数相等时 MAC（内存访问消耗时间, `memory access cost` 缩写为 `MAC` ） 最小, 此时模型速度最快\n  * 减少卷积分组: 过多的 group 操作会增大 MAC, 从而使模型速度变慢\n  * 减少模型分支: 模型中的分支数量越少, 模型速度越快\n  * 减少 `element-wise` 操作: `element-wise` 操作所带来的时间消耗远比在 FLOPs 上的体现的数值要多, 因此要尽可能减少 `element-wise` 操作。 `depthwise convolution` 也具有低 FLOPs 、高 MAC 的特点。\n\n#### Vision Transformer\n\n* TRT-ViT: TensorRT-oriented Vision Transformer，[论文](https:\u002F\u002Farxiv.org\u002Fabs\u002F2205.09579)，[解读](https:\u002F\u002Fwww.yuque.com\u002Flart\u002Fpapers\u002Fpghqxg)。\n  * stage-level：Transformer block 适合放置到模型的后期，这可以最大化效率和性能的权衡。\n  * stage-level：先浅后深的 stage 设计模式可以提升性能。\n  * block-level：Transformer 和 BottleNeck 的混合 block 要比单独的 Transformer 更有效。\n  * block-level：先全局再局部的 block 设计模式有助于弥补性能问题。\n\n#### 通用思路\n\n* 降低复杂度: 例如模型裁剪和剪枝, 减少模型层数和参数规模\n* 改模型结构: 例如模型蒸馏, 通过知识蒸馏方法来获取小模型\n\n### 推理加速\n\n#### 半精度与权重量化\n\n在推理中使用低精度 ( `FP16` 甚至 `INT8` 、二值网络、三值网络) 表示取代原有精度 ( `FP32` ) 表示。\n\n* `TensorRT` 是 NVIDIA 提出的神经网络推理 (Inference) 引擎, 支持训练后 8BIT 量化, 它使用基于交叉熵的模型量化算法, 通过最小化两个分布的差异程度来实现\n* Pytorch1.3 开始已经支持量化功能, 基于 QNNPACK 实现, 支持训练后量化, 动态量化和量化感知训练等技术\n* 另外 `Distiller` 是 Intel 基于 Pytorch 开源的模型优化工具, 自然也支持 Pytorch 中的量化技术\n* 微软的 `NNI` 集成了多种量化感知的训练算法, 并支持 `PyTorch\u002FTensorFlow\u002FMXNet\u002FCaffe2` 等多个开源框架\n\n更多细节可参考 [有三 AI:【杂谈】当前模型量化有哪些可用的开源工具?](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002F3uUwf9vQmQ4jkGjLxzb9aQ)。\n\n#### 操作融合\n\n* [模型推理加速技巧：融合 BN 和 Conv 层 - 小小将的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F110552861)\n* [网络 inference 阶段 conv 层和 BN 层的融合 - autocyz 的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F48005099)\n* [PyTorch 本身提供了类似的功能](https:\u002F\u002Fpytorch.org\u002Fdocs\u002F1.3.0\u002Fquantization.html#torch.quantization.fuse_modules)\n\n#### 重参数化（Re-Parameterization）\n\n* [RepVGG](httsp:\u002F\u002Farxiv.org\u002Fabs\u002F2101.03697)\n  * [RepVGG|让你的 ConVNet 一卷到底，plain 网络首次超过 80%top1 精度](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002FM4Kspm6hO3W8fXT_JqoEhA)\n\n### 时间分析\n\n* Python 自带了几个性能分析的模块 `profile` , `cProfile` 和 `hotshot` , 使用方法基本都差不多, 无非模块是纯 Python 还是用 C 写的。\n* [PyTorch Profiler](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fprofiler.html?highlight=profile#module-torch.profiler) 是一种工具，可在训练和推理过程中收集性能指标。Profiler 的上下文管理器 API 可用于更好地了解哪种模型算子成本最高，检查其输入形状和堆栈记录，研究设备内核活动并可视化执行记录。\n\n### 项目推荐\n\n* [基于 Pytorch 实现模型压缩](https:\u002F\u002Fgithub.com\u002F666DZY666\u002Fmodel-compression):\n  * 量化:8\u002F4\u002F2 bits(dorefa)、三值\u002F二值 (twn\u002Fbnn\u002Fxnor-net)。\n  * 剪枝: 正常、规整、针对分组卷积结构的通道剪枝。\n  * 分组卷积结构。\n  * 针对特征二值量化的 BN 融合。\n\n### 扩展阅读\n\n* [pytorch dataloader 数据加载占用了大部分时间, 各位大佬都是怎么解决的? - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F307282137)\n* [使用 pytorch 时, 训练集数据太多达到上千万张, Dataloader 加载很慢怎么办? - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F356829360)\n* [PyTorch 有哪些坑\u002Fbug? - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F67209417)\n* [Optimizing PyTorch training code](https:\u002F\u002Fsagivtech.com\u002F2017\u002F09\u002F19\u002Foptimizing-pytorch-training-code\u002F)\n* [26 秒单 GPU 训练 CIFAR10, Jeff Dean 也点赞的深度学习优化技巧 - 机器之心的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F79020733)\n* [线上模型加入几个新特征训练后上线, tensorflow serving 预测时间为什么比原来慢 20 多倍? - TzeSing 的回答 - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F354086469\u002Fanswer\u002F894235805)\n* [深度学习模型压缩](https:\u002F\u002Fwww.yuque.com\u002Flart\u002Fgw5mta)\n* [今天, 你的模型加速了吗? 这里有 5 个方法供你参考(附代码解析)](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002F_ATSwwVqigvqmDB0Y9lOAQ)\n* [pytorch 常见的坑汇总 - 郁振波的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F77952356)\n* [Pytorch 提速指南 - 云梦的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F39752167)\n* [优化 PyTorch 的速度和内存效率（2022）](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002FShgNdizIPzeXOREoz8rgJA)\n\n## PyTorch 节省显存\n\n> 原始文档:\u003Chttps:\u002F\u002Fwww.yuque.com\u002Flart\u002Fugkv9f\u002Fnvffyf>\n>\n> 整理自: Pytorch 有什么节省内存 (显存) 的小技巧? - 知乎 \u003Chttps:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F274635237>\n\n### 使用 In-Place 操作\n\n* 对于默认支持 `inplace` 的操作尽量启用。比如 `relu` 可以使用 `inplace=True` 。\n* 可以将 `batchnorm` 和一些特定的激活函数打包成 [`inplace_abn`](https:\u002F\u002Fgithub.com\u002Fmapillary\u002Finplace_abn)。\n\n### 损失函数\n\n每次循环结束时删除 loss, 可以节约很少显存, 但聊胜于无。可见 [Tensor to Variable and memory freeing best practices](https:\u002F\u002Fdiscuss.pytorch.org\u002Ft\u002Ftensor-to-variable-and-memory-freeing-best-practices\u002F6000\u002F2)\n\n### 混合精度\n\n可以节约一定的显存并提速, 但是要小心一些不安全的操作如 mean 和 sum。\n\n* 混合精度训练的介绍文章：\n  * [由浅入深的混合精度训练教程](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002F6FCumAWa8fZ1r7xwIRC9ow)\n* [`NVIDIA\u002FApex`](https:\u002F\u002Fgithub.com\u002Fnvidia\u002Fapex) 提供的混合精度支持。\n  * [PyTorch 必备神器 | 唯快不破：基于 Apex 的混合精度加速](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002FHQnI8rzPvZN6Q_5c8d1nVQ)\n  * [Pytorch 安装 APEX 疑难杂症解决方案 - 陈瀚可的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F80386137)\n* [PyTorch1.6 开始提供的`torch.cuda.amp`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Famp_examples.html) 以支持混合精度。\n\n### 管理不需要反向传播的操作\n\n* 对于不需要反向传播的前向阶段，如验证和推理期间，使用 `torch.no_grad` 来包裹代码。\n  * 注意 `model.eval()` 不等于 `torch.no_grad()` , 请看如下讨论: ['model.eval()' vs 'with torch.no_grad()'](https:\u002F\u002Fdiscuss.pytorch.org\u002Ft\u002Fmodel-eval-vs-with-torch-no-grad\u002F19615)\n* 将不需要计算梯度的变量的 `requires_grad` 设为 `False`, 让变量不参与梯度的后向传播，以减少不必要的梯度的显存占用。\n* 移除不需要计算的梯度路径：\n  * [Stochastic Backpropagation: A Memory Efficient Strategy for Training Video Models](https:\u002F\u002Farxiv.org\u002Fabs\u002F2203.16755)，解读可见：\n    * \u003Chttps:\u002F\u002Fwww.yuque.com\u002Flart\u002Fpapers\u002Fxu5t00>\n    * \u003Chttps:\u002F\u002Fblog.csdn.net\u002FP_LarT\u002Farticle\u002Fdetails\u002F124978961>\n\n### 显存清理\n\n* `torch.cuda.empty_cache()` 这是 `del` 的进阶版, 使用 `nvidia-smi` 会发现显存有明显的变化. 但是训练时最大的显存占用似乎没变. 大家可以试试: [How can we release GPU memory cache?](https:\u002F\u002Fdiscuss.pytorch.org\u002Ft\u002Fhow-can-we-release-gpu-memory-cache\u002F14530)\n* 可以使用 `del` 删除不必要的中间变量, 或者使用 `replacing variables` 的形式来减少占用.\n\n### 梯度累加（Gradient Accumulation）\n\n把一个 `batchsize=64` 分为两个 32 的 batch，两次 forward 以后，backward 一次。但会影响 `batchnorm` 等和 `batchsize` 相关的层。\n\n在 [PyTorch 的文档](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Famp_examples.html#gradient-accumulation) 中提到了梯度累加与混合精度并用的例子。\n\n使用梯度累加技术可以对分布式训练加速，这可以参考：[[原创][深度][PyTorch] DDP 系列第三篇：实战与技巧 - 996 黄金一代的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F250471767)\n\n### 梯度检查点（Gradient Checkpointing）\n\nPyTorch 中提供了 [`torch.utils.checkpoint`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002F1.11\u002Fcheckpoint.html#torch-utils-checkpoint)。这是通过在反向传播期间，在每个检查点位置重新执行一次前向传播来实现的。\n\n论文 [Training Deep Nets with Sublinear Memory Cost](https:\u002F\u002Farxiv.org\u002Fabs\u002F1604.06174) 基于梯度检查点技术，将显存从 O(N) 降到了 O(sqrt(N))。对于越深的模型, 这个方法省的显存就越多, 且速度不会明显变慢。\n\n* [PyTorch 之 Checkpoint 机制解析](https:\u002F\u002Fwww.yuque.com\u002Flart\u002Fugkv9f\u002Fazvnyg)\n* [torch.utils.checkpoint 简介 和 简易使用](https:\u002F\u002Fblog.csdn.net\u002Fone_six_mix\u002Farticle\u002Fdetails\u002F93937091)\n* [Sublinear Memory Cost 的一份 PyTorch 实现](https:\u002F\u002Fgithub.com\u002FLyken17\u002Fpytorch-memonger)，参考自：[Pytorch 有什么节省内存(显存)的小技巧? - Lyken 的回答 - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F274635237\u002Fanswer\u002F755102181)\n\n### 相关工具\n\n* These codes can help you to detect your GPU memory during training with Pytorch. [https:\u002F\u002Fgithub.com\u002FOldpan\u002FPytorch-Memory-Utils](https:\u002F\u002Fgithub.com\u002FOldpan\u002FPytorch-Memory-Utils)\n* Just less than nvidia-smi? [https:\u002F\u002Fgithub.com\u002Fwookayin\u002Fgpustat](https:\u002F\u002Fgithub.com\u002Fwookayin\u002Fgpustat)\n\n### 参考资料\n\n* [Pytorch 有什么节省内存(显存)的小技巧? - 郑哲东的回答 - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F274635237\u002Fanswer\u002F573633662)\n* [浅谈深度学习: 如何计算模型以及中间变量的显存占用大小](https:\u002F\u002Foldpan.me\u002Farchives\u002Fhow-to-calculate-gpu-memory)\n* [如何在 Pytorch 中精细化利用显存](https:\u002F\u002Foldpan.me\u002Farchives\u002Fhow-to-use-memory-pytorch)\n* [Pytorch 有什么节省显存的小技巧? - 陈瀚可的回答 - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F274635237\u002Fanswer\u002F756144739)\n* [PyTorch 显存机制分析 - Connolly 的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F424512257)\n\n## 其他技巧\n\n### 重现\n\n可关注文档中 [相关章节](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Frandomness.html#reproducibility)。\n\n#### 强制确定性操作\n\n[避免使用非确定性算法](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Frandomness.html#avoiding-nondeterministic-algorithms)。\n\nPyTorch 中，[`torch.use_deterministic_algorithms()`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fgenerated\u002Ftorch.use_deterministic_algorithms.html#torch.use_deterministic_algorithms) 可以强制使用确定性算法而不是非确定性算法，并且如果已知操作是非确定性的（并且没有确定性的替代方案），则会抛出错误。\n\n#### 设置随机数种子\n\n```python\ndef seed_torch(seed=1029):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed) # if you are using multi-GPU.\n    torch.backends.cudnn.benchmark = False\n    torch.backends.cudnn.deterministic = True\n\nseed_torch()\n```\n\n参考自\u003Chttps:\u002F\u002Fwww.zdaiot.com\u002FMLFrameworks\u002FPytorch\u002FPytorch%E9%9A%8F%E6%9C%BA%E7%A7%8D%E5%AD%90\u002F>\n\n#### PyTorch 1.9 版本前 DataLoader 中的隐藏 BUG\n\n具体细节可见 [可能 95%的人还在犯的 PyTorch 错误 - serendipity 的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F523239005)\n\n解决方法可参考 [文档](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Frandomness.html#dataloader)：\n\n```python\ndef seed_worker(worker_id):\n    worker_seed = torch.initial_seed() % 2**32\n    numpy.random.seed(worker_seed)\n    random.seed(worker_seed)\n\nDataLoader(..., worker_init_fn=seed_worker)\n```\n","# PyTorch 的一些技巧\n\n## 更改记录\n\n* 2019年11月29日：更新了一些模型设计技巧和推理加速的内容，补充了下 apex 的一个介绍链接，~~另外删了 tfrecord, pytorch 能用么? 这个我记得是不能, 所以删掉了~~(表示删掉:\u003C)\n* 2019年11月30日：补充 MAC 的含义，补充 ShuffleNetV2 的论文链接\n* 2019年12月02日：之前说的 pytorch 不能用 tfrecord，今天看到\u003Chttps:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F358632497>下的一个回答，涨姿势了\n* 2019年12月23日：补充几篇关于模型压缩量化的科普性文章\n* 2020年2月7日：从文章中摘录了一点注意事项，补充在了 [代码层面](#代码层面) 小节\n* 2020年4月30日：\n  * 添加了一个 github 的文档备份\n  * 补充了卷积层和 BN 层融合的介绍的链接\n  * 另外这里说明下，对于之前参考的很多朋友的文章和回答，没有把链接和对应的内容提要关联在一起，估计会导致一些朋友阅读时相关的内容时的提问，无法问到原作者，这里深感抱歉。\n  * 调整部分内容，将内容尽量与参考链接相对应\n* 2020年5月18日：补充一些关于 PyTorch 节省显存的技巧。同时简单调整格式。另外发现一个之前的错误：`non_blocking=False` 的建议应该是 `non_blocking=True` 。\n* 2021年01月06日：调整下关于读取图片数据的一些介绍。\n* 2021年01月13日：补充了一条推理加速的策略。我觉得我应该先更新 github 的文档，知乎答案的更新有点麻烦，也没法比较更改信息，就很费劲。\n* 2022年6月26日：重新调整了下格式和内容安排，同时补充了更多的参考资料和一些最新发现的有效内容。\n* 2024年6月20日：简单调整格式，补充了基于 `tar` 格式和 `IterableDataset` 的一种加速数据读取的思路。\n\n## PyTorch 提速\n\n> [!note]\n> 原始文档：\u003Chttps:\u002F\u002Fwww.yuque.com\u002Flart\u002Fugkv9f\u002Fugysgn>\n>\n> 声明：大部分内容来自知乎和其他博客的分享，这里只作为一个收集罗列。欢迎给出更多建议。\n\n知乎回答（欢迎点赞哦）：\n\n* [pytorch dataloader 数据加载占用了大部分时间，各位大佬都是怎么解决的？ - 人民艺术家的回答 - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F307282137\u002Fanswer\u002F907835663)\n* [使用 pytorch 时，训练集数据太多达到上千万张，Dataloader 加载很慢怎么办？ - 人民艺术家的回答 - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F356829360\u002Fanswer\u002F907832358)\n\n### 预处理提速\n\n* 尽量减少每次读取数据时的预处理操作，可以考虑把一些固定的操作，例如 `resize` ，事先处理好保存下来，训练的时候直接拿来用。\n* 将预处理搬到 GPU 上加速。\n  * Linux 可以使用 [`NVIDIA\u002FDALI`](https:\u002F\u002Fgithub.com\u002FNVIDIA\u002FDALI)。\n  * 使用基于 Tensor 的图像处理操作。\n\n### IO 提速\n\n* mmcv 对数据的读取提供了比较高效且全面的支持：[OpenMMLab：MMCV 核心组件分析(三)：FileClient](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F339190576)\n\n#### 使用更快的图片处理\n\n* `opencv` 一般要比 `PIL` 要快。\n  * 请注意，`PIL` 的惰性加载的策略使得其看上去 `open` 要比 `opencv` 的 `imread` 要快，但是实际上那并没有完全加载数据。可以对 `open` 返回的对象调用其 `load()` 方法，从而手动加载数据，这时的速度才是合理的。\n* 对于 `jpeg` 读取，可以尝试 `jpeg4py`。\n* 存 `bmp` 图（降低解码时间）。\n* 关于不同图像处理库速度的讨论：[Python 的各种 imread 函数在实现方式和读取速度上有何区别？ - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F48762352)\n\n#### 整合数据为单个连续文件（降低读取次数）\n\n对于大规模的小文件读取，可以保存为一个可以连续读取的连续文件格式。[可以选择考虑 `TFRecord (Tensorflow)` , `recordIO`, `hdf5`, `pth`, `n5`, `lmdb`等](https:\u002F\u002Fgithub.com\u002FLyken17\u002FEfficient-PyTorch#data-loader)。\n\n* `TFRecord` ：\u003Chttps:\u002F\u002Fgithub.com\u002Fvahidk\u002Ftfrecord>\n* `lmdb` 数据库：\n  * \u003Chttps:\u002F\u002Fgithub.com\u002FFangyh09\u002FImage2LMDB>\n  * \u003Chttps:\u002F\u002Fblog.csdn.net\u002FP_LarT\u002Farticle\u002Fdetails\u002F103208405>\n  * \u003Chttps:\u002F\u002Fgithub.com\u002Flartpang\u002FPySODToolBox\u002Fblob\u002Fmaster\u002FForBigDataset\u002FImageFolder2LMDB.py>\n* 基于 [`Tar`文件和`IterableDataset`的实现](https:\u002F\u002Fgithub.com\u002Fvahidk\u002FEffectivePyTorch?tab=readme-ov-file#building-efficient-custom-data-loaders)\n\n#### 预读取数据\n\n预读取下一次迭代需要的数据。使用案例：\n\n* [如何给你 PyTorch 里的 Dataloader 打鸡血 - MKFMIKU 的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F66145913)\n* [给 pytorch 读取数据加速 - 体 hi 的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F72956595)\n\n#### 借助内存\n\n* 直接载到内存里面。\n  * 将图片读取后存到一个固定的容器对象中。\n    * YoloV5 中的 [`--cache`](https:\u002F\u002Fgithub.com\u002Fultralytics\u002Fyolov5\u002Fblob\u002F19f33cbae29ac2127dd877b52e228c178dda6086\u002Futils\u002Fdataloaders.py#L521-L534)。\n* 把内存映射成磁盘。\n\n#### 借助固态\n\n机械硬盘换成 NVME 固态。参考自 [如何给你 PyTorch 里的 Dataloader 打鸡血 - MKFMIKU 的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F66145913)\n\n### 训练策略\n\n#### 低精度训练\n\n在训练中使用低精度（`FP16` 甚至 `INT8`、二值网络、三值网络）表示取代原有精度（`FP32`）表示。\n\n可以节约一定的显存并提速，但是要小心一些不安全的操作如 mean 和 sum。\n\n* 混合精度训练的介绍文章：\n  * [由浅入深的混合精度训练教程](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002F6FCumAWa8fZ1r7xwIRC9ow)\n* [`NVIDIA\u002FApex`](https:\u002F\u002Fgithub.com\u002Fnvidia\u002Fapex) 提供的混合精度支持。\n  * [PyTorch 必备神器 | 唯快不破：基于 Apex 的混合精度加速](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002FHQnI8rzPvZN6Q_5c8d1nVQ)\n  * [Pytorch 安装 APEX 疑难杂症解决方案 - 陈瀚可的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F80386137)\n* [PyTorch1.6 开始提供的`torch.cuda.amp`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Famp_examples.html) 以支持混合精度。\n\n#### 更大的 batch\n\n更大的 batch 在固定的 epoch 的情况下往往会带来更短的训练时间。但是大的 batch 面临着超参数的设置、显存占用问题等诸多考量，这又是另一个备受关注的领域了。\n\n* 超参数设置\n  * Accurate, large minibatch SGD: training imagenet in 1 hour，[论文](https:\u002F\u002Farxiv.org\u002Fabs\u002F1706.02677)\n* 优化显存占用\n  * [Gradient Accumulation](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Famp_examples.html#gradient-accumulation)\n  * [Gradient Checkpointing](https:\u002F\u002Fpytorch.org\u002Fdocs\u002F1.11\u002Fcheckpoint.html#torch-utils-checkpoint)\n    * Training deep nets with sublinear memory cost，[论文](https:\u002F\u002Farxiv.org\u002Fabs\u002F1604.06174)\n  * In-Place Operation\n    * In-Place Activated BatchNorm for Memory-Optimized Training of DNNs，[论文](https:\u002F\u002Farxiv.org\u002Fabs\u002F1712.02616)，[代码](https:\u002F\u002Fgithub.com\u002Fmapillary\u002Finplace_abn)\n\n### 代码层面\n\n#### 库设置\n\n* 在训练循环之前设置 `torch.backends.cudnn.benchmark = True` 可以加速计算。由于计算不同内核大小卷积的 cuDNN 算法的性能不同，自动调优器可以运行一个基准来找到最佳算法。当你的输入大小不经常改变时，建议开启这个设置。如果输入大小经常改变，那么自动调优器就需要太频繁地进行基准测试，这可能会损害性能。它可以将向前和向后传播速度提高 1.27x 到 1.70x。\n* 使用页面锁定内存，即在 DataLoader 中设定 [`pin_memory=True`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fdata.html#memory-pinning)。\n* 合适的 `num_worker`，细节讨论可见 [Pytorch 提速指南 - 云梦的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F39752167)。\n* [optimizer.zero_grad(set_to_none=False](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fgenerated\u002Ftorch.optim.Optimizer.zero_grad.html#torch-optim-optimizer-zero-grad) 这里可以通过设置 `set_to_none=True` 来降低的内存占用，并且可以适度提高性能。但是这也会改变某些行为，具体可见文档。通过 `model.zero_grad()` 或 `optimizer.zero_grad()` 将对所有参数执行 `memset`，并通过读写操作更新梯度。但是，将梯度设置为 `None` 将不会执行 `memset`，并且将使用“只写”操作更新梯度。因此，设置梯度为 `None` 更快。\n* 反向传播期间设定使用 `eval` 模式并使用 `torch.no_grad` 关闭梯度计算。\n* 可以考虑使用 [channels_last](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Ftensor_attributes.html#torch-memory-format) 的内存格式。\n* [用`DistributedDataParallel`代替`DataParallel`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Fcuda.html#use-nn-parallel-distributeddataparallel-instead-of-multiprocessing-or-nn-dataparallel)。对于多 GPU 来说，即使只有单个节点，也总是优先使用 `DistributedDataParallel` 而不是 `DataParallel` ，因为 `DistributedDataParallel` 应用于多进程，并为每个 GPU 创建一个进程，从而绕过 Python 全局解释器锁 (GIL) 并提高速度。\n\n#### 模型\n\n* 不要初始化任何用不到的变量，因为 PyTorch 的初始化和 `forward` 是分开的，他不会因为你不去使用，而不去初始化。\n* [`@torch.jit.script`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fgenerated\u002Ftorch.jit.script.html#torch.jit.script)，使用 PyTroch JIT 将逐点运算融合到单个 CUDA kernel 上。PyTorch 优化了维度很大的张量的运算操作。在 PyTorch 中对小张量进行太多的运算操作是非常低效的。所以有可能的话，将计算操作都重写为批次（batch）的形式，可以减少消耗和提高性能。而如果没办法自己手动实现批次的运算操作，那么可以采用 TorchScript 来提升代码的性能。TorchScript 是一个 Python 函数的子集，但经过了 PyTorch 的验证，PyTorch 可以通过其 just in time(jtt) 编译器来自动优化 TorchScript 代码，提高性能。但更好的做法还是手动实现批次的运算操作。\n* 在使用混合精度的 FP16 时，对于所有不同架构设计，设置尺寸为 8 的倍数。\n* BN 之前的卷积层可以去掉 bias。因为在数学上，bias 可以通过 BN 的均值减法来抵消。我们可以节省模型参数、运行时的内存。\n\n#### 数据\n\n* 将 batch size 设置为 8 的倍数，最大化 GPU 内存的使用。\n* GPU 上尽可能执行 NumPy 风格的操作。\n* 使用 `del` 释放内存占用。\n* 避免不同设备之间不必要的数据传输。\n* 创建张量的时候，直接指定设备，而不要创建后再传输到目标设备上。\n* 使用 [`torch.from_numpy(ndarray)`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fgenerated\u002Ftorch.from_numpy.html#torch-from-numpy) 或者 [`torch.as_tensor(data, dtype=None, device=None)`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fgenerated\u002Ftorch.as_tensor.html#torch-as-tensor)，这可以通过共享内存而避免重新申请空间，具体使用细节和注意事项可参考对应文档。如果源设备和目标设备都是 CPU，`torch.from_numpy` 和 `torch.as_tensor` 不会拷贝数据。如果源数据是 NumPy 数组，使用 `torch.from_numpy` 更快。如果源数据是一个具有相同数据类型和设备类型的张量，那么 `torch.as_tensor` 可以避免拷贝数据，这里的数据可以是 Python 的 list， tuple，或者张量。\n* 使用非阻塞传输，即设定 `non_blocking=True` 。这会在可能的情况下尝试异步转换，例如，将页面锁定内存中的 CPU 张量转换为 CUDA 张量。\n\n### 对优化器的优化\n\n* 将模型参数存放到一块连续的内存中，从而减少 `optimizer.step()` 的时间。\n  * [`contiguous_pytorch_params`](https:\u002F\u002Fgithub.com\u002FPhilJd\u002Fcontiguous_pytorch_params)\n* 使用 APEX 中的 [fused building blocks](https:\u002F\u002Fnvidia.github.io\u002Fapex\u002Foptimizers.html)\n\n### 模型设计\n\n#### CNN\n\n* ShuffleNetV2，[论文](https:\u002F\u002Farxiv.org\u002Fpdf\u002F1807.11164.pdf)。\n  * 卷积层输入输出通道一致: 卷积层的输入和输出特征通道数相等时 MAC（内存访问消耗时间, `memory access cost` 缩写为 `MAC` ） 最小, 此时模型速度最快\n  * 减少卷积分组: 过多的 group 操作会增大 MAC, 从而使模型速度变慢\n  * 减少模型分支: 模型中的分支数量越少, 模型速度越快\n  * 减少 `element-wise` 操作: `element-wise` 操作所带来的时间消耗远比在 FLOPs 上的体现的数值要多, 因此要尽可能减少 `element-wise` 操作。 `depthwise convolution` 也具有低 FLOPs 、高 MAC 的特点。\n\n#### Vision Transformer\n\n* TRT-ViT: TensorRT-oriented Vision Transformer，[论文](https:\u002F\u002Farxiv.org\u002Fabs\u002F2205.09579)，[解读](https:\u002F\u002Fwww.yuque.com\u002Flart\u002Fpapers\u002Fpghqxg)。\n  * stage-level：Transformer block 适合放置到模型的后期，这可以最大化效率和性能的权衡。\n  * stage-level：先浅后深的 stage 设计模式可以提升性能。\n  * block-level：Transformer 和 BottleNeck 的混合 block 要比单独的 Transformer 更有效。\n  * block-level：先全局再局部的 block 设计模式有助于弥补性能问题。\n\n#### 通用思路\n\n* 降低复杂度: 例如模型裁剪和剪枝, 减少模型层数和参数规模\n* 改模型结构: 例如模型蒸馏, 通过知识蒸馏方法来获取小模型\n\n### 推理加速\n\n#### 半精度与权重量化\n\n在推理中使用低精度 ( `FP16` 甚至 `INT8` 、二值网络、三值网络) 表示取代原有精度 ( `FP32` ) 表示。\n\n* `TensorRT` 是 NVIDIA 提出的神经网络推理 (Inference) 引引擎, 支持训练后 8BIT 量化, 它使用基于交叉熵的模型量化算法, 通过最小化两个分布的差异程度来实现\n* Pytorch1.3 开始已经支持量化功能, 基于 QNNPACK 实现, 支持训练后量化, 动态量化和量化感知训练等技术\n* 右外 `Distiller` 是 Intel 基于 Pytorch 开源的模型优化工具, 自然也支持 Pytorch 中的量化技术\n* 微软的 `NNI` 集成了多种量化感知的训练算法, 并支持 `PyTorch\u002FTensorFlow\u002FMXNet\u002FCaffe2` 等多个开源框架\n\n更多细节可参考 [有三 AI:【杂谈】当前模型量化有哪些可用的开源工具?](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002F3uUwf9vQmQ4jkGjLxzb9aQ)。\n\n#### 操作融合\n\n* [模型推理加速技巧：融合 BN 和 Conv 层 - 小小将的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F110552861)\n* [网络 inference 阶段 conv 层和 BN 层的融合 - autocyz 的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F48005099)\n* [PyTorch 本身提供了类似的功能](https:\u002F\u002Fpytorch.org\u002Fdocs\u002F1.3.0\u002Fquantization.html#torch.quantization.fuse_modules)\n\n#### 重参数化（Re-Parameterization）\n\n* [RepVGG](httsp:\u002F\u002Farxiv.org\u002Fabs\u002F2101.03697)\n  * [RepVGG|让你的 ConVNet 一卷到底，plain 网络首次超过 80%top1 精度](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002FM4Kspm6hO3W8fXT_JqoEhA)\n\n### 时间分析\n\n* Python 自带了几个性能分析的模块 `profile` , `cProfile` 和 `hotshot` , 使用方法基本都差不多, 无非模块是纯 Python 还是用 C 写的。\n* [PyTorch Profiler](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fprofiler.html?highlight=profile#module-torch.profiler) 是一种工具，可在训练和推理过程中收集性能指标。Profiler 的上下文管理器 API 可用于更好地了解哪种模型算子成本最高，检查其输入形状和堆栈记录，研究设备内核活动并可视化执行记录。\n\n### 项目推荐\n\n* [基于 Pytorch 实现模型压缩](https:\u002F\u002Fgithub.com\u002F666DZY666\u002Fmodel-compression):\n  * 量化:8\u002F4\u002F2 bits(dorefa)、三值\u002F二值 (twn\u002Fbnn\u002Fxnor-net)。\n  * 剪枝: 正常、规整、针对分组卷积结构的通道剪枝。\n  * 分组卷积结构。\n  * 针对特征二值量化的 BN 融合。\n\n### 扩展阅读\n\n* [pytorch dataloader 数据加载占用了大部分时间, 各位大佬都是怎么解决的? - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F307282137)\n* [使用 pytorch 时, 训练集数据太多达到上千万张, Dataloader 加载很慢怎么办? - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F356829360)\n* [PyTorch 有哪些坑\u002Fbug? - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F67209417)\n* [Optimizing PyTorch training code](https:\u002F\u002Fsagivtech.com\u002F2017\u002F09\u002F19\u002Foptimizing-pytorch-training-code\u002F)\n* [26 秒单 GPU 训练 CIFAR10, Jeff Dean 也点赞的深度学习优化技巧 - 机器之心的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F79020733)\n* [线上模型加入几个新特征训练后上线, tensorflow serving 预测时间为什么比原来慢 20 多倍? - TzeSing 的回答 - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F354086469\u002Fanswer\u002F894235805)\n* [深度学习模型压缩](https:\u002F\u002Fwww.yuque.com\u002Flart\u002Fgw5mta)\n* [今天, 你的模型加速了吗? 这里有 5 个方法供你参考(附代码解析)](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002F_ATSwwVqigvqmDB0Y9lOAQ)\n* [pytorch 常见的坑汇总 - 郁振波的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F77952356)\n* [Pytorch 提速指南 - 云梦的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F39752167)\n* [优化 PyTorch 的速度和内存效率（2022）](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002FShgNdizIPzeXOREoz8rgJA)\n\n## PyTorch 节省显存\n\n> 原始文档:\u003Chttps:\u002F\u002Fwww.yuque.com\u002Flart\u002Fugkv9f\u002Fnvffyf>\n>\n> 整理自: Pytorch 有什么节省内存 (显存) 的小技巧? - 知乎 \u003Chttps:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F274635237>\n\n### 使用 In-Place 操作\n\n* 对于默认支持 `inplace` 的操作尽量启用。比如 `relu` 可以使用 `inplace=True` 。\n* 可以将 `batchnorm` 和一些特定的激活函数打包成 [`inplace_abn`](https:\u002F\u002Fgithub.com\u002Fmapillary\u002Finplace_abn)。\n\n### 损失函数\n\n每次循环结束时删除 loss, 可以节约很少显存, 但聊胜于无。可见 [Tensor to Variable and memory freeing best practices](https:\u002F\u002Fdiscuss.pytorch.org\u002Ft\u002Ftensor-to-variable-and-memory-freeing-best-practices\u002F6000\u002F2)\n\n### 混合精度\n\n可以节约一定的显存并提速, 但是要小心一些不安全的操作如 mean 和 sum。\n\n* 混合精度训练的介绍文章：\n  * [由浅入深的混合精度训练教程](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002F6FCumAWa8fZ1r7xwIRC9ow)\n* [`NVIDIA\u002FApex`](https:\u002F\u002Fgithub.com\u002Fnvidia\u002Fapex) 提供的混合精度支持。\n  * [PyTorch 必备神器 | 唯快不破：基于 Apex 的混合精度加速](https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002FHQnI8rzPvZN6Q_5c8d1nVQ)\n  * [Pytorch 安装 APEX 疑难杂症解决方案 - 陈瀚可的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F80386137)\n* [PyTorch1.6 开始提供的`torch.cuda.amp`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Famp_examples.html) 以支持混合精度。\n\n### 管理不需要反向传播的操作\n\n* 对于不需要反向传播的前向阶段，如验证和推理期间，使用 `torch.no_grad` 来包裹代码。\n  * 注意 `model.eval()` 不等于 `torch.no_grad()` , 请看如下讨论: ['model.eval()' vs 'with torch.no_grad()'](https:\u002F\u002Fdiscuss.pytorch.org\u002Ft\u002Fmodel-eval-vs-with-torch-no-grad\u002F19615)\n* 将不需要计算梯度的变量的 `requires_grad` 设为 `False`, 让变量不参与梯度的后向传播，以减少不必要的梯度的显存占用。\n* 移除不需要计算的梯度路径：\n  * [Stochastic Backpropagation: A Memory Efficient Strategy for Training Video Models](https:\u002F\u002Farxiv.org\u002Fabs\u002F2203.16755)，解读可见：\n    * \u003Chttps:\u002F\u002Fwww.yuque.com\u002Flart\u002Fpapers\u002Fxu5t00>\n    * \u003Chttps:\u002F\u002Fblog.csdn.net\u002FP_LarT\u002Farticle\u002Fdetails\u002F124978961>\n\n### 显存清理\n\n* `torch.cuda.empty_cache()` 这是 `del` 的进阶版, 使用 `nvidia-smi` 会发现显存有明显的变化. 但是训练时最大的显存占用似乎没变. 大家可以试试: [How can we release GPU memory cache?](https:\u002F\u002Fdiscuss.pytorch.org\u002Ft\u002Fhow-can-we-release-gpu-memory-cache\u002F14530)\n* 可以使用 `del` 删除不必要的中间变量, 或者使用 `replacing variables` 的形式来减少占用.\n\n### 梯度累加（Gradient Accumulation）\n\n把一个 `batchsize=64` 分为两个 32 的 batch，两次 forward 以后，backward 一次。但会影响 `batchnorm` 等和 `batchsize` 相关的层。\n\n在 [PyTorch 的文档](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Famp_examples.html#gradient-accumulation) 中提到了梯度累加与混合精度并用的例子。\n\n使用梯度累加技术可以对分布式训练加速，这可以参考：[[原创][深度][PyTorch] DDP 系列第三篇：实战与技巧 - 996 黄金一代的文章 - 知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F250471767)\n\n### 梯度检查点（Gradient Checkpointing）\n\nPyTorch 中提供了 [`torch.utils.checkpoint`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002F1.11\u002Fcheckpoint.html#torch-utils-checkpoint)。这是通过在反向传播期间，在每个检查点位置重新执行一次前向传播来实现的。\n\n论文 [Training Deep Nets with Sublinear Memory Cost](https:\u002F\u002Farxiv.org\u002Fabs\u002F1604.06174) 基于梯度检查点技术，将显存从 O(N) 降到了 O(sqrt(N))。对于越深的模型, 这个方法省的显存就越多, 且速度不会明显变慢。\n\n* [PyTorch 之 Checkpoint 机制解析](https:\u002F\u002Fwww.yuque.com\u002Flart\u002Fugkv9f\u002Fazvnyg)\n* [torch.utils.checkpoint 简介 和 简易使用](https:\u002F\u002Fblog.csdn.net\u002Fone_six_mix\u002Farticle\u002Fdetails\u002F93937091)\n* [Sublinear Memory Cost 的一份 PyTorch 实现](https:\u002F\u002Fgithub.com\u002FLyken17\u002Fpytorch-memonger)，参考自：[Pytorch 有什么节省内存(显存)的小技巧? - Lyken 的回答 - 知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F274635237\u002Fanswer\u002F755102181)\n\n### 相关工具\n\n* These codes can help you to detect your GPU memory during training with Pytorch. [https:\u002F\u002Fgithub.com\u002FOldpan\u002FPytorch-Memory-Utils](https:\u002F\u002Fgithub.com\u002FOldpan\u002FPytorch-Memory-Utils)\n* Just less than nvidia-smi? [https:\u002F\u002Fgithub.com\u002Fwookayin\u002Fgpustat](https:\u002F\u002Fgithub.com\u002Fwookayin\u002Fgpustat)\n\n### 参考资料\n\n* [PyTorch 有哪些节省内存（显存）的小技巧？——郑哲东的回答——知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F274635237\u002Fanswer\u002F573633662)\n* [浅谈深度学习：如何计算模型以及中间变量的显存占用大小](https:\u002F\u002Foldpan.me\u002Farchives\u002Fhow-to-calculate-gpu-memory)\n* [如何在 PyTorch 中精细化利用显存](https:\u002F\u002Foldpan.me\u002Farchives\u002Fhow-to-use-memory-pytorch)\n* [PyTorch 有哪些节省显存的小技巧？——陈瀚可的回答——知乎](https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F274635237\u002Fanswer\u002F756144739)\n* [PyTorch 显存机制分析——Connolly 的文章——知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F424512257)\n\n## 其他技巧\n\n### 可复现性\n\n可关注文档中[相关章节](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Frandomness.html#reproducibility)。\n\n#### 强制执行确定性操作\n\n[避免使用非确定性算法](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Frandomness.html#avoiding-nondeterministic-algorithms)。\n\n在 PyTorch 中，[`torch.use_deterministic_algorithms()`](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fgenerated\u002Ftorch.use_deterministic_algorithms.html#torch.use_deterministic_algorithms) 可以强制使用确定性算法而非非确定性算法；如果已知某操作是非确定性的（且没有确定性的替代方案），则会抛出错误。\n\n#### 设置随机数种子\n\n```python\ndef seed_torch(seed=1029):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed) # 如果使用多 GPU。\n    torch.backends.cudnn.benchmark = False\n    torch.backends.cudnn.deterministic = True\n\nseed_torch()\n```\n\n参考自\u003Chttps:\u002F\u002Fwww.zdaiot.com\u002FMLFrameworks\u002FPytorch\u002FPytorch%E9%9A%8F%E6%9C%BA%E7%A7%8D%E5%AD%90\u002F>\n\n#### PyTorch 1.9 版本前 DataLoader 中的隐藏 BUG\n\n具体细节可见[可能 95%的人还在犯的 PyTorch 错误——serendipity 的文章——知乎](https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F523239005)。\n\n解决方法可参考[文档](https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnotes\u002Frandomness.html#dataloader)：\n\n```python\ndef seed_worker(worker_id):\n    worker_seed = torch.initial_seed() % 2**32\n    numpy.random.seed(worker_seed)\n    random.seed(worker_seed)\n\nDataLoader(..., worker_init_fn=seed_worker)\n```","# PyTorchTricks 快速上手指南\n\nPyTorchTricks 并非一个需要安装的独立 Python 库，而是一份汇集了 PyTorch 训练加速、显存优化及模型设计技巧的实战知识库。本指南将帮助你快速配置高效开发环境，并应用核心代码技巧。\n\n## 环境准备\n\n在开始应用这些技巧前，请确保你的开发环境满足以下要求：\n\n*   **操作系统**: Linux (推荐 Ubuntu\u002FCentOS) 或 Windows。部分 IO 加速技巧（如 NVIDIA DALI）在 Linux 下支持更好。\n*   **Python 版本**: 建议 Python 3.8 及以上。\n*   **PyTorch 版本**: 建议 PyTorch 1.6+（以原生支持 `torch.cuda.amp` 混合精度），推荐使用最新稳定版以获取最佳性能算子。\n*   **硬件依赖**:\n    *   NVIDIA GPU (支持 CUDA)。\n    *   对于大规模数据读取加速，强烈建议使用 **NVMe SSD**。\n*   **前置依赖库** (根据需求选择性安装):\n    *   图像处理加速: `opencv-python`, `jpeg4py`\n    *   GPU 数据预处理: `nvidia-dali-cuda110` (需匹配 CUDA 版本)\n    *   混合精度训练 (旧版): `nvidia-apex` (若使用 PyTorch 1.6+ 可仅用原生 AMP)\n    *   高效数据格式: `lmdb`, `h5py`\n\n## 安装步骤\n\n由于本项目是代码片段与策略集合，无需执行 `pip install pytorchtricks`。请根据你的需求安装上述提到的增强库。\n\n### 1. 基础环境安装 (推荐国内镜像)\n\n```bash\n# 安装 PyTorch (示例：CUDA 11.8 版本，使用清华镜像源)\npip install torch torchvision torchaudio --index-url https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\n\n# 安装常用加速依赖\npip install opencv-python jpeg4py lmdb h5py --index-url https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\n```\n\n### 2. 可选：安装 NVIDIA Apex (如需高级混合精度功能)\n\n如果需要使用 Apex 的融合优化器（Fused Optimizers），需从源码编译安装：\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002FNVIDIA\u002Fapex.git\ncd apex\n# 注意：需根据实际 CUDA 版本调整参数，--cpp_ext --cuda_ext 开启扩展\npip install -v --no-cache-dir . --global-option=\"--cpp_ext\" --global-option=\"--cuda_ext\"\n```\n\n### 3. 可选：安装 NVIDIA DALI (GPU 数据预处理)\n\n```bash\n# 示例：安装对应 CUDA 11.x 的 DALI 版本\npip install nvidia-dali-cuda110 --extra-index-url https:\u002F\u002Fdeveloper.download.nvidia.com\u002Fcompute\u002Fredist\n```\n\n## 基本使用\n\n以下是基于文档内容提炼的三个最核心的“即插即用”代码技巧，可直接集成到你的训练脚本中。\n\n### 1. 全局加速配置 (代码层面)\n\n在训练脚本初始化阶段（定义 DataLoader 和模型之前）加入以下设置，可显著提升卷积计算效率并减少内存碎片。\n\n```python\nimport torch\n\n# 1. 开启 cuDNN 自动调优：当输入尺寸固定时，可提升 1.27x-1.70x 速度\ntorch.backends.cudnn.benchmark = True\n\n# 2. 设置张量内存格式为 channels_last (针对特定 CNN 架构可加速)\n# 需在模型输入处应用，例如：input = input.to(memory_format=torch.channels_last)\n\n# 3. 优化梯度清零方式：使用 set_to_none=True 节省显存并提速\n# 在训练循环中替换 optimizer.zero_grad()\n# optimizer.zero_grad(set_to_none=True) \n```\n\n### 2. 高效数据加载 (IO 提速)\n\n配置 `DataLoader` 以利用多进程、页锁定内存和非阻塞传输，最大化 GPU 利用率。\n\n```python\nfrom torch.utils.data import DataLoader, Dataset\n\n# 假设已有自定义 dataset\n# dataset = MyDataset(...)\n\ntrain_loader = DataLoader(\n    dataset,\n    batch_size=64,              # 建议设置为 8 的倍数以最大化 GPU 效率\n    shuffle=True,\n    num_workers=8,              # 根据 CPU 核心数调整，避免过高导致上下文切换开销\n    pin_memory=True,            # 启用页锁定内存，加速 CPU->GPU 传输\n    drop_last=True,             # 丢弃最后不足一个 batch 的数据，利于静态图优化\n    prefetch_factor=2,          # 预读取批次数量\n    persistent_workers=True     # 保持 worker 进程存活，减少启动开销\n)\n\n# 在训练循环中移动数据到 GPU 时，使用非阻塞传输\nfor inputs, targets in train_loader:\n    # non_blocking=True 允许数据传输与计算重叠\n    inputs = inputs.cuda(non_blocking=True)\n    targets = targets.cuda(non_blocking=True)\n    \n    # ... 后续训练逻辑\n```\n\n### 3. 混合精度训练 (显存优化与提速)\n\n使用 PyTorch 原生的 `torch.cuda.amp` 进行半精度训练，可在几乎不损失精度的情况下大幅降低显存占用并加快计算。\n\n```python\nimport torch\nimport torch.nn as nn\nfrom torch.cuda.amp import autocast, GradScaler\n\nmodel = MyModel().cuda()\noptimizer = torch.optim.SGD(model.parameters(), lr=0.1)\ncriterion = nn.CrossEntropyLoss()\n\n# 初始化梯度缩放器\nscaler = GradScaler()\n\nfor epoch in range(num_epochs):\n    for inputs, targets in train_loader:\n        inputs, targets = inputs.cuda(), targets.cuda()\n        \n        optimizer.zero_grad(set_to_none=True)\n        \n        # 开启自动混合精度上下文\n        with autocast():\n            outputs = model(inputs)\n            loss = criterion(outputs, targets)\n        \n        # 反向传播：scaler 会自动处理梯度缩放\n        scaler.scale(loss).backward()\n        \n        # 更新参数：scaler 会自动取消缩放并执行 step\n        scaler.step(optimizer)\n        \n        # 更新缩放因子\n        scaler.update()\n```\n\n### 4. 模型结构微调建议\n\n在定义模型架构时，遵循以下原则可进一步提升速度：\n\n*   **移除冗余 Bias**: 卷积层后紧跟 BatchNorm 时，设置 `bias=False`。\n    ```python\n    # 推荐写法\n    conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, bias=False)\n    bn = nn.BatchNorm2d(out_channels)\n    ```\n*   **In-place 激活函数**: 减少中间变量显存占用。\n    ```python\n    # 推荐写法\n    self.relu = nn.ReLU(inplace=True)\n    ```\n*   **通道数对齐**: 设计 CNN 时，尽量使卷积层的输入\u002F输出通道数为 8 的倍数，且尽量保持一致，以减少内存访问成本 (MAC)。","某计算机视觉团队正在训练一个基于千万级高清图片的目标检测模型，但受限于数据加载瓶颈和显存限制，迭代效率极低。\n\n### 没有 PyTorchTricks 时\n- **IO 读取缓慢**：直接遍历海量独立小文件（如 JPEG），频繁的文件系统调用导致 `Dataloader` 成为主要耗时点，GPU 经常处于空闲等待状态。\n- **预处理拖累 CPU**：每张图在 CPU 上实时进行 `resize` 和格式转换，且使用了较慢的 `PIL` 库，多进程也无法完全掩盖延迟。\n- **显存易爆炸**：坚持使用 `FP32` 全精度训练，导致无法增大 `Batch Size`，收敛速度慢且容易因显存溢出（OOM）中断实验。\n- **硬盘性能瓶颈**：数据存储在机械硬盘上，随机读取速度极慢，严重制约了大规模数据集的吞吐能力。\n\n### 使用 PyTorchTricks 后\n- **连续文件加速 IO**：采纳将数据整合为 `LMDB` 或基于 `Tar` + `IterableDataset` 的方案，将随机读取变为顺序读取，大幅降低文件系统开销。\n- **高效预处理流水线**：切换至 `OpenCV` 或 `jpeg4py` 进行解码，并将部分固定预处理（如 Resize）提前离线完成，甚至利用 `DALI` 将图像处理卸载到 GPU。\n- **混合精度节省显存**：引入 `torch.cuda.amp` 或 `Apex` 进行 `FP16` 混合精度训练，在保持精度的前提下显存占用减半，成功将 `Batch Size` 提升一倍。\n- **硬件与缓存优化**：配合 NVMe 固态硬盘，并利用内存缓存机制（类似 YOLOv5 的 `--cache`）预加载热点数据，彻底消除 I\u002FO 等待。\n\n通过整合数据读取、预处理优化及混合精度训练等实战技巧，PyTorchTricks 帮助团队将原本被 I\u002FO 和显存卡住的训练流程提速数倍，显著缩短了模型研发周期。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Flartpang_PyTorchTricks_a0e684ce.png","lartpang","Yooweey","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Flartpang_2f8fc65e.png","人生南北多歧路，水流花谢知何处。","PhD & BS @ DUT","China",null,"https:\u002F\u002Flartpang.github.io","https:\u002F\u002Fgithub.com\u002Flartpang",1193,124,"2026-03-15T14:26:07",1,"Linux","需要 NVIDIA GPU (用于 CUDA 加速、混合精度训练及 TensorRT 推理)，具体显存大小取决于模型和 Batch Size，建议使用支持 cuDNN 的显卡","未说明 (建议根据数据集大小配置，文中提及可将数据载入内存或使用内存映射)",{"notes":92,"python":93,"dependencies":94},"本项目为 PyTorch 技巧集合而非单一可执行工具，无固定安装依赖。文中明确提到 NVIDIA DALI 仅支持 Linux；推荐使用 NVMe 固态硬盘提升 IO 速度；涉及混合精度训练、量化及 TensorRT 加速时需确保硬件和驱动支持；部分优化技巧（如 cudnn.benchmark）适用于输入尺寸固定的场景。","未说明 (需兼容 PyTorch，文中提及 PyTorch 1.3\u002F1.6\u002F2.x 等版本特性)",[95,96,97,98,99,100,101,102],"torch","torchvision","NVIDIA\u002FApex (可选，用于混合精度)","opencv-python (推荐)","jpeg4py (可选)","lmdb (可选)","mmcv (可选)","NVIDIA\u002FDALI (可选，Linux)",[13],[105,106,107,108],"pytorch","pytorch-trick","pytorch-tutorial","tricks","2026-03-27T02:49:30.150509","2026-04-06T05:17:01.210602",[],[]]