[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-davda54--sam":3,"tool-davda54--sam":61},[4,18,26,36,44,53],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":17},4358,"openclaw","openclaw\u002Fopenclaw","OpenClaw 是一款专为个人打造的本地化 AI 助手，旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚，能够直接接入你日常使用的各类通讯渠道，包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息，OpenClaw 都能即时响应，甚至支持在 macOS、iOS 和 Android 设备上进行语音交互，并提供实时的画布渲染功能供你操控。\n\n这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地，用户无需依赖云端服务即可享受快速、私密的智能辅助，真正实现了“你的数据，你做主”。其独特的技术亮点在于强大的网关架构，将控制平面与核心助手分离，确保跨平台通信的流畅性与扩展性。\n\nOpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者，以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力（支持 macOS、Linux 及 Windows WSL2），即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你",349277,3,"2026-04-06T06:32:30",[13,14,15,16],"Agent","开发框架","图像","数据工具","ready",{"id":19,"name":20,"github_repo":21,"description_zh":22,"stars":23,"difficulty_score":10,"last_commit_at":24,"category_tags":25,"status":17},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,"2026-04-05T11:01:52",[14,15,13],{"id":27,"name":28,"github_repo":29,"description_zh":30,"stars":31,"difficulty_score":32,"last_commit_at":33,"category_tags":34,"status":17},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 真正成长为懂上",149489,2,"2026-04-10T11:32:46",[14,13,35],"语言模型",{"id":37,"name":38,"github_repo":39,"description_zh":40,"stars":41,"difficulty_score":32,"last_commit_at":42,"category_tags":43,"status":17},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 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",108322,"2026-04-10T11:39:34",[14,15,13],{"id":45,"name":46,"github_repo":47,"description_zh":48,"stars":49,"difficulty_score":32,"last_commit_at":50,"category_tags":51,"status":17},6121,"gemini-cli","google-gemini\u002Fgemini-cli","gemini-cli 是一款由谷歌推出的开源 AI 命令行工具，它将强大的 Gemini 大模型能力直接集成到用户的终端环境中。对于习惯在命令行工作的开发者而言，它提供了一条从输入提示词到获取模型响应的最短路径，无需切换窗口即可享受智能辅助。\n\n这款工具主要解决了开发过程中频繁上下文切换的痛点，让用户能在熟悉的终端界面内直接完成代码理解、生成、调试以及自动化运维任务。无论是查询大型代码库、根据草图生成应用，还是执行复杂的 Git 操作，gemini-cli 都能通过自然语言指令高效处理。\n\n它特别适合广大软件工程师、DevOps 人员及技术研究人员使用。其核心亮点包括支持高达 100 万 token 的超长上下文窗口，具备出色的逻辑推理能力；内置 Google 搜索、文件操作及 Shell 命令执行等实用工具；更独特的是，它支持 MCP（模型上下文协议），允许用户灵活扩展自定义集成，连接如图像生成等外部能力。此外，个人谷歌账号即可享受免费的额度支持，且项目基于 Apache 2.0 协议完全开源，是提升终端工作效率的理想助手。",100752,"2026-04-10T01:20:03",[52,13,15,14],"插件",{"id":54,"name":55,"github_repo":56,"description_zh":57,"stars":58,"difficulty_score":32,"last_commit_at":59,"category_tags":60,"status":17},4721,"markitdown","microsoft\u002Fmarkitdown","MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具，专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片（含 OCR）、音频（含语音转录）、HTML 乃至 YouTube 链接等多种格式的解析，能够精准提取文档中的标题、列表、表格和链接等关键结构信息。\n\n在人工智能应用日益普及的今天，大语言模型（LLM）虽擅长处理文本，却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点，它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式，成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外，它还提供了 MCP（模型上下文协议）服务器，可无缝集成到 Claude Desktop 等 LLM 应用中。\n\n这款工具特别适合开发者、数据科学家及 AI 研究人员使用，尤其是那些需要构建文档检索增强生成（RAG）系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性，但其核心优势在于为机器",93400,"2026-04-06T19:52:38",[52,14],{"id":62,"github_repo":63,"name":64,"description_en":65,"description_zh":66,"ai_summary_zh":66,"readme_en":67,"readme_zh":68,"quickstart_zh":69,"use_case_zh":70,"hero_image_url":71,"owner_login":72,"owner_name":73,"owner_avatar_url":74,"owner_bio":75,"owner_company":76,"owner_location":77,"owner_email":78,"owner_twitter":79,"owner_website":80,"owner_url":81,"languages":82,"stars":87,"forks":88,"last_commit_at":89,"license":90,"difficulty_score":91,"env_os":92,"env_gpu":93,"env_ram":94,"env_deps":95,"category_tags":99,"github_topics":100,"view_count":32,"oss_zip_url":104,"oss_zip_packed_at":104,"status":17,"created_at":105,"updated_at":106,"faqs":107,"releases":136},6372,"davda54\u002Fsam","sam","SAM: Sharpness-Aware Minimization (PyTorch)","SAM（Sharpness-Aware Minimization）是一款基于 PyTorch 的优化器工具，旨在通过同时最小化损失值与损失锐度，显著提升深度学习模型的泛化能力。传统优化方法往往只关注找到损失函数的最低点，却容易陷入尖锐的局部极小值，导致模型在未知数据上表现不佳；而 SAM 专门寻找那些周围邻域损失均较低的平坦极小值区域。这种机制不仅让模型在多个数据集上达到了业界领先的性能，还赋予其极强的抗标签噪声鲁棒性。\n\n从技术实现来看，SAM 作为一个轻量级封装器，可无缝对接 SGD 等基础优化器。其核心亮点在于独特的“两步更新”策略：每次迭代需进行两次前向与反向传播，先探测损失曲面的锐度方向，再执行针对性的参数更新，从而引导模型收敛至更宽、更稳定的最优解。不过需要注意的是，由于计算量加倍，训练速度约为常规方法的一半，且在使用批归一化（BatchNorm）时需留意统计量的计算时机。\n\nSAM 非常适合从事深度学习算法研究的研究人员，以及希望提升模型最终表现和稳定性的 AI 开发者。如果你正在处理噪声较大的数据集，或追求极致的泛化效果，SAM 是一个值得尝试的高效解决方案。","\u003Ch1 align=\"center\">\u003Cb>(Adaptive) SAM Optimizer\u003C\u002Fb>\u003C\u002Fh1>\n\u003Ch3 align=\"center\">\u003Cb>Sharpness-Aware Minimization for Efficiently Improving Generalization\u003C\u002Fb>\u003C\u002Fh3>\n\u003Cp align=\"center\">\n  \u003Ci>~ in Pytorch ~\u003C\u002Fi>\n\u003C\u002Fp> \n \n--------------\n\n\u003Cbr>\n\nSAM simultaneously minimizes loss value and loss sharpness. In particular, it seeks parameters that lie in **neighborhoods having uniformly low loss**. SAM improves model generalization and yields [SoTA performance for several datasets](https:\u002F\u002Fpaperswithcode.com\u002Fpaper\u002Fsharpness-aware-minimization-for-efficiently-1). Additionally, it provides robustness to label noise on par with that provided by SoTA procedures that specifically target learning with noisy labels.\n\nThis is an **unofficial** repository for [Sharpness-Aware Minimization for Efficiently Improving Generalization](https:\u002F\u002Farxiv.org\u002Fabs\u002F2010.01412) and [ASAM: Adaptive Sharpness-Aware Minimization for Scale-Invariant Learning of Deep Neural Networks](https:\u002F\u002Farxiv.org\u002Fabs\u002F2102.11600). Implementation-wise, SAM class is a light wrapper that computes the regularized \"sharpness-aware\" gradient, which is used by the underlying optimizer (such as SGD with momentum). This repository also includes a simple [WRN for Cifar10](example); as a proof-of-concept, it beats the performance of SGD with momentum on this dataset.\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fdavda54_sam_readme_ddc2182b1375.png\" alt=\"Loss landscape with and without SAM\" width=\"512\"\u002F>  \n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Csub>\u003Cem>ResNet loss landscape at the end of training with and without SAM. Sharpness-aware updates lead to a significantly wider minimum, which then leads to better generalization properties.\u003C\u002Fem>\u003C\u002Fsub>\n\u003C\u002Fp>\n\n\u003Cbr>\n\n## Usage\n\nIt should be straightforward to use SAM in your training pipeline. Just keep in mind that the training will run twice as slow, because SAM needs two forward-backward passes to estime the \"sharpness-aware\" gradient. If you're using gradient clipping, make sure to change only the magnitude of gradients, not their direction.\n\n```python\nfrom sam import SAM\n...\n\nmodel = YourModel()\nbase_optimizer = torch.optim.SGD  # define an optimizer for the \"sharpness-aware\" update\noptimizer = SAM(model.parameters(), base_optimizer, lr=0.1, momentum=0.9)\n...\n\nfor input, output in data:\n\n  # first forward-backward pass\n  loss = loss_function(output, model(input))  # use this loss for any training statistics\n  loss.backward()\n  optimizer.first_step(zero_grad=True)\n  \n  # second forward-backward pass\n  loss_function(output, model(input)).backward()  # make sure to do a full forward pass\n  optimizer.second_step(zero_grad=True)\n...\n```\n\n\u003Cbr>\n\n**Alternative usage with a single closure-based `step` function**. This alternative offers similar API to native PyTorch optimizers like LBFGS (kindly suggested by [@rmcavoy](https:\u002F\u002Fgithub.com\u002Frmcavoy)):\n\n```python\nfrom sam import SAM\n...\n\nmodel = YourModel()\nbase_optimizer = torch.optim.SGD  # define an optimizer for the \"sharpness-aware\" update\noptimizer = SAM(model.parameters(), base_optimizer, lr=0.1, momentum=0.9)\n...\n\nfor input, output in data:\n  def closure():\n    loss = loss_function(output, model(input))\n    loss.backward()\n    return loss\n\n  loss = loss_function(output, model(input))\n  loss.backward()\n  optimizer.step(closure)\n  optimizer.zero_grad()\n...\n```\n\n### Training tips\n- [@hjq133](https:\u002F\u002Fgithub.com\u002Fhjq133): The suggested usage can potentially cause problems if you use batch normalization. The running statistics are computed in both forward passes, but they should be computed only for the first one. A possible solution is to set BN momentum to zero (kindly suggested by [@ahmdtaha](https:\u002F\u002Fgithub.com\u002Fahmdtaha)) to bypass the running statistics during the second pass. An example usage is on lines [51](https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam\u002Fblob\u002Fcdcbdc1574022d3a3c3240da136378c38562d51d\u002Fexample\u002Ftrain.py#L51) and [58](https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam\u002Fblob\u002Fcdcbdc1574022d3a3c3240da136378c38562d51d\u002Fexample\u002Ftrain.py#L58) in [example\u002Ftrain.py](https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam\u002Fblob\u002Fcdcbdc1574022d3a3c3240da136378c38562d51d\u002Fexample\u002Ftrain.py):\n```python\nfor batch in dataset.train:\n  inputs, targets = (b.to(device) for b in batch)\n\n  # first forward-backward step\n  enable_running_stats(model)  # \u003C- this is the important line\n  predictions = model(inputs)\n  loss = smooth_crossentropy(predictions, targets)\n  loss.mean().backward()\n  optimizer.first_step(zero_grad=True)\n\n  # second forward-backward step\n  disable_running_stats(model)  # \u003C- this is the important line\n  smooth_crossentropy(model(inputs), targets).mean().backward()\n  optimizer.second_step(zero_grad=True)\n```\n\n- [@evanatyourservice](https:\u002F\u002Fgithub.com\u002Fevanatyourservice): If you plan to train on multiple GPUs, the paper states that *\"To compute the SAM update when parallelizing across multiple accelerators, we divide each data batch evenly among the accelerators, independently compute the SAM gradient on each accelerator, and average the resulting sub-batch SAM gradients to obtain the final SAM update.\"* This can be achieved by the following code:\n```python\nfor input, output in data:\n  # first forward-backward pass\n  loss = loss_function(output, model(input))\n  with model.no_sync():  # \u003C- this is the important line\n    loss.backward()\n  optimizer.first_step(zero_grad=True)\n  \n  # second forward-backward pass\n  loss_function(output, model(input)).backward()\n  optimizer.second_step(zero_grad=True)\n```\n- [@evanatyourservice](https:\u002F\u002Fgithub.com\u002Fevanatyourservice): Adaptive SAM reportedly performs better than the original SAM. The ASAM paper suggests to use higher `rho` for the adaptive updates (~10x larger)\n\n- [@mlaves](https:\u002F\u002Fgithub.com\u002Fmlaves): LR scheduling should be either applied to the base optimizer or you should use SAM with a single `step` call (with a closure):\n```python\nscheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer.base_optimizer, T_max=200)\n```\n- [@AlbertoSabater](https:\u002F\u002Fgithub.com\u002FAlbertoSabater): Integration with Pytorch Lightning — you can write the `training_step` function as:\n```python\ndef training_step(self, batch, batch_idx):\n    optimizer = self.optimizers()\n\n    # first forward-backward pass\n    loss_1 = self.compute_loss(batch)\n    self.manual_backward(loss_1, optimizer)\n    optimizer.first_step(zero_grad=True)\n\n    # second forward-backward pass\n    loss_2 = self.compute_loss(batch)\n    self.manual_backward(loss_2, optimizer)\n    optimizer.second_step(zero_grad=True)\n\n    return loss_1\n```\n\u003Cbr>\n\n\n## Documentation\n\n#### `SAM.__init__`\n\n| **Argument**    | **Description** |\n| :-------------- | :-------------- |\n| `params` (iterable) | iterable of parameters to optimize or dicts defining parameter groups |\n| `base_optimizer` (torch.optim.Optimizer) | underlying optimizer that does the \"sharpness-aware\" update |\n| `rho` (float, optional)           | size of the neighborhood for computing the max loss *(default: 0.05)* |\n| `adaptive` (bool, optional)       | set this argument to True if you want to use an experimental implementation of element-wise Adaptive SAM *(default: False)* |\n| `**kwargs` | keyword arguments passed to the `__init__` method of `base_optimizer` |\n\n\u003Cbr>\n\n#### `SAM.first_step`\n\nPerforms the first optimization step that finds the weights with the highest loss in the local `rho`-neighborhood.\n\n| **Argument**    | **Description** |\n| :-------------- | :-------------- |\n| `zero_grad` (bool, optional) | set to True if you want to automatically zero-out all gradients after this step *(default: False)* |\n\n\u003Cbr>\n\n#### `SAM.second_step`\n\nPerforms the second optimization step that updates the original weights with the gradient from the (locally) highest point in the loss landscape.\n\n| **Argument**    | **Description** |\n| :-------------- | :-------------- |\n| `zero_grad` (bool, optional) | set to True if you want to automatically zero-out all gradients after this step *(default: False)* |\n\n\u003Cbr>\n\n#### `SAM.step`\n\nPerforms both optimization steps in a single call. This function is an alternative to explicitly calling `SAM.first_step` and `SAM.second_step`.\n\n| **Argument**    | **Description** |\n| :-------------- | :-------------- |\n| `closure` (callable) | the closure should do an additional full forward and backward pass on the optimized model *(default: None)* |\n\n\n\n\n\u003Cbr>\n\n## Experiments\n\nI've verified that SAM works on a simple WRN 16-8 model run on CIFAR10; you can replicate the experiment by running [train.py](example\u002Ftrain.py). The Wide-ResNet is enhanced only by label smoothing and the most basic image augmentations with cutout, so the errors are higher than those in the [SAM paper](https:\u002F\u002Farxiv.org\u002Fabs\u002F2010.01412). Theoretically, you can get even lower errors by running for longer (1800 epochs instead of 200), because SAM shouldn't be as prone to overfitting. SAM uses `rho=0.05`, while ASAM is set to `rho=2.0`, as [suggested by its authors](https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam\u002Fissues\u002F37).\n\n| Optimizer             | Test error rate |\n| :-------------------- |   -----: |\n| SGD + momentum        |   3.20 % |\n| SAM + SGD + momentum  |   2.86 % |\n| ASAM + SGD + momentum |   2.55 % |\n\n\n\u003Cbr>\n\n## Cite\n\nPlease cite the original authors if you use this optimizer in your work:\n\n```bibtex\n@inproceedings{foret2021sharpnessaware,\n  title={Sharpness-aware Minimization for Efficiently Improving Generalization},\n  author={Pierre Foret and Ariel Kleiner and Hossein Mobahi and Behnam Neyshabur},\n  booktitle={International Conference on Learning Representations},\n  year={2021},\n  url={https:\u002F\u002Fopenreview.net\u002Fforum?id=6Tm1mposlrM}\n}\n```\n\n```bibtex\n@inproceesings{pmlr-v139-kwon21b,\n  title={ASAM: Adaptive Sharpness-Aware Minimization for Scale-Invariant Learning of Deep Neural Networks},\n  author={Kwon, Jungmin and Kim, Jeongseop and Park, Hyunseo and Choi, In Kwon},\n  booktitle ={Proceedings of the 38th International Conference on Machine Learning},\n  pages={5905--5914},\n  year={2021},\n  editor={Meila, Marina and Zhang, Tong},\n  volume={139},\n  series={Proceedings of Machine Learning Research},\n  month={18--24 Jul},\n  publisher ={PMLR},\n  pdf={http:\u002F\u002Fproceedings.mlr.press\u002Fv139\u002Fkwon21b\u002Fkwon21b.pdf},\n  url={https:\u002F\u002Fproceedings.mlr.press\u002Fv139\u002Fkwon21b.html},\n  abstract={Recently, learning algorithms motivated from sharpness of loss surface as an effective measure of generalization gap have shown state-of-the-art performances. Nevertheless, sharpness defined in a rigid region with a fixed radius, has a drawback in sensitivity to parameter re-scaling which leaves the loss unaffected, leading to weakening of the connection between sharpness and generalization gap. In this paper, we introduce the concept of adaptive sharpness which is scale-invariant and propose the corresponding generalization bound. We suggest a novel learning method, adaptive sharpness-aware minimization (ASAM), utilizing the proposed generalization bound. Experimental results in various benchmark datasets show that ASAM contributes to significant improvement of model generalization performance.}\n}\n```\n","\u003Ch1 align=\"center\">\u003Cb>（自适应）SAM 优化器\u003C\u002Fb>\u003C\u002Fh1>\n\u003Ch3 align=\"center\">\u003Cb>锐度感知最小化：高效提升泛化能力\u003C\u002Fb>\u003C\u002Fh3>\n\u003Cp align=\"center\">\n  \u003Ci>~ 基于 PyTorch ~\u003C\u002Fi>\n\u003C\u002Fp> \n \n--------------\n\n\u003Cbr>\n\nSAM 同时最小化损失值和损失的锐度。具体而言，它寻找位于**具有均匀低损失的邻域**中的参数。SAM 能够提升模型的泛化能力，并在多个数据集上达到 [当前最优性能](https:\u002F\u002Fpaperswithcode.com\u002Fpaper\u002Fsharpness-aware-minimization-for-efficiently-1)。此外，它对标签噪声的鲁棒性与专门针对带噪声标签学习的当前最优方法相当。\n\n这是一个关于 [锐度感知最小化：高效提升泛化能力](https:\u002F\u002Farxiv.org\u002Fabs\u002F2010.01412) 和 [ASAM：用于深度神经网络尺度不变学习的自适应锐度感知最小化](https:\u002F\u002Farxiv.org\u002Fabs\u002F2102.11600) 的 **非官方** 代码库。从实现上看，SAM 类是一个轻量级封装，用于计算正则化的“锐度感知”梯度，该梯度由底层优化器（如带有动量的 SGD）使用。本仓库还包含一个简单的 [CIFAR-10 WRN 示例](example)；作为概念验证，它在该数据集上的表现优于带有动量的 SGD。\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fdavda54_sam_readme_ddc2182b1375.png\" alt=\"有 SAM 与无 SAM 的损失景观\" width=\"512\"\u002F>  \n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Csub>\u003Cem>训练结束时，ResNet 在有 SAM 和无 SAM 情况下的损失景观。锐度感知更新会导致更宽的极小值区域，从而带来更好的泛化性能。\u003C\u002Fem>\u003C\u002Fsub>\n\u003C\u002Fp>\n\n\u003Cbr>\n\n## 使用方法\n\n在你的训练流程中使用 SAM 应该非常直观。需要注意的是，训练速度会减慢一倍，因为 SAM 需要两次前向和反向传播来估计“锐度感知”梯度。如果你使用梯度裁剪，请确保只调整梯度的大小，而不改变其方向。\n\n```python\nfrom sam import SAM\n...\n\nmodel = YourModel()\nbase_optimizer = torch.optim.SGD  # 定义用于“锐度感知”更新的优化器\noptimizer = SAM(model.parameters(), base_optimizer, lr=0.1, momentum=0.9)\n...\n\nfor input, output in data:\n\n  # 第一次前向-反向传播\n  loss = loss_function(output, model(input))  # 使用此损失记录任何训练统计信息\n  loss.backward()\n  optimizer.first_step(zero_grad=True)\n  \n  # 第二次前向-反向传播\n  loss_function(output, model(input)).backward()  # 确保完成完整的前向传播\n  optimizer.second_step(zero_grad=True)\n...\n```\n\n\u003Cbr>\n\n**另一种使用方式：基于闭包的单次 `step` 函数**。这种方式提供了与 PyTorch 原生优化器（如 LBFGS）类似的 API（由 [@rmcavoy](https:\u002F\u002Fgithub.com\u002Frmcavoy) 友好建议）：\n\n```python\nfrom sam import SAM\n...\n\nmodel = YourModel()\nbase_optimizer = torch.optim.SGD  # 定义用于“锐度感知”更新的优化器\noptimizer = SAM(model.parameters(), base_optimizer, lr=0.1, momentum=0.9)\n...\n\nfor input, output in data:\n  def closure():\n    loss = loss_function(output, model(input))\n    loss.backward()\n    return loss\n\n  loss = loss_function(output, model(input))\n  loss.backward()\n  optimizer.step(closure)\n  optimizer.zero_grad()\n...\n```\n\n### 训练技巧\n- [@hjq133](https:\u002F\u002Fgithub.com\u002Fhjq133)：如果使用批归一化，上述用法可能会出现问题。运行统计会在两次前向传播中都被计算，但它们应该只在第一次计算。一种可能的解决方案是将 BN 动量设为零（由 [@ahmdtaha](https:\u002F\u002Fgithub.com\u002Fahmdtaha) 友好建议），以避免在第二次传播中更新运行统计。示例用法见 [example\u002Ftrain.py](https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam\u002Fblob\u002Fcdcbdc1574022d3a3c3240da136378c38562d51d\u002Fexample\u002Ftrain.py) 的第 [51](https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam\u002Fblob\u002Fcdcbdc1574022d3a3c3240da136378c38562d51d\u002Fexample\u002Ftrain.py#L51) 和 [58](https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam\u002Fblob\u002Fcdcbdc1574022d3a3c3240da136378c38562d51d\u002Fexample\u002Ftrain.py#L58) 行：\n```python\nfor batch in dataset.train:\n  inputs, targets = (b.to(device) for b in batch)\n\n  # 第一次前向-反向步骤\n  enable_running_stats(model)  # \u003C- 这是关键行\n  predictions = model(inputs)\n  loss = smooth_crossentropy(predictions, targets)\n  loss.mean().backward()\n  optimizer.first_step(zero_grad=True)\n\n  # 第二次前向-反向步骤\n  disable_running_stats(model)  # \u003C- 这是关键行\n  smooth_crossentropy(model(inputs), targets).mean().backward()\n  optimizer.second_step(zero_grad=True)\n```\n\n- [@evanatyourservice](https:\u002F\u002Fgithub.com\u002Fevanatyourservice)：如果计划在多 GPU 上训练，论文指出：“为了在多个加速器之间并行化时计算 SAM 更新，我们将每个数据批次均匀地分配到各个加速器，在每个加速器上独立计算 SAM 梯度，然后对得到的子批次 SAM 梯度取平均，以获得最终的 SAM 更新。”这可以通过以下代码实现：\n```python\nfor input, output in data:\n  # 第一次前向-反向传播\n  loss = loss_function(output, model(input))\n  with model.no_sync():  # \u003C- 这是关键行\n    loss.backward()\n  optimizer.first_step(zero_grad=True)\n  \n  # 第二次前向-反向传播\n  loss_function(output, model(input)).backward()\n  optimizer.second_step(zero_grad=True)\n```\n- [@evanatyourservice](https:\u002F\u002Fgithub.com\u002Fevanatyourservice)：据报道，自适应 SAM 的性能优于原始 SAM。ASAM 论文建议为自适应更新使用更高的 `rho` 参数（约为原始值的 10 倍）。\n\n- [@mlaves](https:\u002F\u002Fgithub.com\u002Fmlaves)：学习率调度应应用于基础优化器，或者你可以使用 SAM 并通过单次 `step` 调用（结合闭包）来实现：\n```python\nscheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer.base_optimizer, T_max=200)\n```\n- [@AlbertoSabater](https:\u002F\u002Fgithub.com\u002FAlbertoSabater)：与 PyTorch Lightning 集成时，可以这样编写 `training_step` 函数：\n```python\ndef training_step(self, batch, batch_idx):\n    optimizer = self.optimizers()\n\n    # 第一次前向-反向传播\n    loss_1 = self.compute_loss(batch)\n    self.manual_backward(loss_1, optimizer)\n    optimizer.first_step(zero_grad=True)\n\n    # 第二次前向-反向传播\n    loss_2 = self.compute_loss(batch)\n    self.manual_backward(loss_2, optimizer)\n    optimizer.second_step(zero_grad=True)\n\n    return loss_1\n```\n\u003Cbr>\n\n## 文档\n\n#### `SAM.__init__`\n\n| **参数**    | **描述** |\n| :-------------- | :-------------- |\n| `params` (可迭代对象) | 需要优化的参数的可迭代对象，或定义参数组的字典 |\n| `base_optimizer` (torch.optim.Optimizer) | 执行“尖锐度感知”更新的基础优化器 |\n| `rho` (float, 可选)           | 用于计算最大损失的邻域大小 *(默认: 0.05)* |\n| `adaptive` (bool, 可选)       | 如果您希望使用基于元素级别的自适应 SAM 的实验性实现，请将此参数设置为 True *(默认: False)* |\n| `**kwargs` | 传递给 `base_optimizer` 的 `__init__` 方法的关键字参数 |\n\n\u003Cbr>\n\n#### `SAM.first_step`\n\n执行第一步优化，找到局部 `rho` 邻域内损失最大的权重。\n\n| **参数**    | **描述** |\n| :-------------- | :-------------- |\n| `zero_grad` (bool, 可选) | 如果您希望在此步骤后自动清零所有梯度，请将其设置为 True *(默认: False)* |\n\n\u003Cbr>\n\n#### `SAM.second_step`\n\n执行第二步优化，根据损失曲面上（局部）最高点的梯度来更新原始权重。\n\n| **参数**    | **描述** |\n| :-------------- | :-------------- |\n| `zero_grad` (bool, 可选) | 如果您希望在此步骤后自动清零所有梯度，请将其设置为 True *(默认: False)* |\n\n\u003Cbr>\n\n#### `SAM.step`\n\n在一次调用中同时执行两个优化步骤。此函数是显式调用 `SAM.first_step` 和 `SAM.second_step` 的替代方案。\n\n| **参数**    | **描述** |\n| :-------------- | :-------------- |\n| `closure` (可调用对象) | 闭包应针对优化后的模型执行一次完整的前向和反向传播 *(默认: None)* |\n\n\n\n\n\u003Cbr>\n\n## 实验\n\n我已验证 SAM 在 CIFAR10 数据集上运行的简单 WRN 16-8 模型上有效；您可以通过运行 [train.py](example\u002Ftrain.py) 来复现该实验。Wide-ResNet 仅通过标签平滑和最基本的图像增强（如 Cutout）进行改进，因此误差高于 [SAM 论文](https:\u002F\u002Farxiv.org\u002Fabs\u002F2010.01412) 中的结果。理论上，如果训练时间更长（例如 1800 轮而不是 200 轮），可以获得更低的误差，因为 SAM 不太容易过拟合。SAM 使用 `rho=0.05`，而 ASAM 则按照其作者的建议设置为 `rho=2.0`，详见 [GitHub 问题 #37](https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam\u002Fissues\u002F37)。\n\n| 优化器             | 测试错误率 |\n| :-------------------- |   -----: |\n| SGD + 动量        |   3.20 % |\n| SAM + SGD + 动量  |   2.86 % |\n| ASAM + SGD + 动量 |   2.55 % |\n\n\n\u003Cbr>\n\n## 引用\n\n如果您在工作中使用此优化器，请引用原始作者：\n\n```bibtex\n@inproceedings{foret2021sharpnessaware,\n  title={Sharpness-aware Minimization for Efficiently Improving Generalization},\n  author={Pierre Foret and Ariel Kleiner and Hossein Mobahi and Behnam Neyshabur},\n  booktitle={International Conference on Learning Representations},\n  year={2021},\n  url={https:\u002F\u002Fopenreview.net\u002Fforum?id=6Tm1mposlrM}\n}\n```\n\n```bibtex\n@inproceesings{pmlr-v139-kwon21b,\n  title={ASAM: Adaptive Sharpness-Aware Minimization for Scale-Invariant Learning of Deep Neural Networks},\n  author={Kwon, Jungmin and Kim, Jeongseop and Park, Hyunseo and Choi, In Kwon},\n  booktitle ={Proceedings of the 38th International Conference on Machine Learning},\n  pages={5905--5914},\n  year={2021},\n  editor={Meila, Marina and Zhang, Tong},\n  volume={139},\n  series={Proceedings of Machine Learning Research},\n  month={18--24 Jul},\n  publisher ={PMLR},\n  pdf={http:\u002F\u002Fproceedings.mlr.press\u002Fv139\u002Fkwon21b\u002Fkwon21b.pdf},\n  url={https:\u002F\u002Fproceedings.mlr.press\u002Fv139\u002Fkwon21b.html},\n  abstract={近年来，以损失曲面的尖锐度作为泛化差距的有效度量的学习算法取得了最先进的性能。然而，在固定半径的刚性区域内定义的尖锐度，存在对参数缩放敏感的缺点，这会导致损失不变，从而削弱了尖锐度与泛化差距之间的联系。本文引入了尺度不变的自适应尖锐度概念，并提出了相应的泛化界。我们提出了一种新的学习方法——自适应尖锐度感知最小化（ASAM），并利用所提出的泛化界进行优化。在多个基准数据集上的实验结果表明，ASAM 显著提升了模型的泛化性能。}\n}\n```","# SAM (Sharpness-Aware Minimization) 快速上手指南\n\nSAM 是一种通过同时最小化损失值和损失锐度（loss sharpness）来提升模型泛化能力的优化器。它寻找具有统一低损失的参数邻域，能有效提升模型在各类数据集上的表现，并对标签噪声具有鲁棒性。本指南基于非官方 PyTorch 实现。\n\n## 环境准备\n\n*   **系统要求**: Linux, macOS, Windows\n*   **Python 版本**: Python 3.6+\n*   **核心依赖**:\n    *   PyTorch >= 1.6.0\n    *   torchvision (可选，用于示例中的数据集加载)\n*   **前置知识**: 熟悉 PyTorch 的基本训练循环流程。\n\n## 安装步骤\n\n该工具未发布到 PyPI，需直接从 GitHub 源码安装。\n\n**方式一：使用 pip 直接安装（推荐）**\n\n```bash\npip install git+https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam.git\n```\n\n**方式二：克隆仓库后安装（适合国内网络不稳定时手动下载）**\n\n如果直接访问 GitHub 较慢，可先手动下载代码包或使用国内镜像加速的 git 代理，然后执行：\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam.git\ncd sam\npip install -e .\n```\n\n## 基本使用\n\nSAM 的核心机制是需要进行两次前向传播和反向传播（two forward-backward passes），因此训练速度约为普通优化器的一半。\n\n### 1. 标准用法（分步执行）\n\n这是最直观的使用方式，明确区分第一步（寻找最差点）和第二步（更新权重）。\n\n```python\nfrom sam import SAM\nimport torch\n\n# 初始化模型\nmodel = YourModel()\n\n# 定义基础优化器 (如 SGD)\nbase_optimizer = torch.optim.SGD\n\n# 初始化 SAM 优化器\n# rho: 邻域大小，默认 0.05；adaptive: 是否启用自适应版本 (ASAM)\noptimizer = SAM(model.parameters(), base_optimizer, lr=0.1, momentum=0.9)\n\nfor input, output in data:\n    # --- 第一次前向 - 反向传播 ---\n    # 计算损失并反向传播\n    loss = loss_function(output, model(input))\n    loss.backward()\n    # 执行第一步：找到局部邻域内损失最大的权重方向\n    optimizer.first_step(zero_grad=True)\n    \n    # --- 第二次前向 - 反向传播 ---\n    # 再次计算损失并反向传播 (确保完成完整的前向过程)\n    loss_function(output, model(input)).backward()\n    # 执行第二步：根据第一步找到的方向更新原始权重\n    optimizer.second_step(zero_grad=True)\n```\n\n### 2. 进阶用法（闭包模式）\n\n如果你习惯使用类似 `LBFGS` 的闭包风格，可以使用单步调用模式：\n\n```python\nfrom sam import SAM\n\nmodel = YourModel()\nbase_optimizer = torch.optim.SGD\noptimizer = SAM(model.parameters(), base_optimizer, lr=0.1, momentum=0.9)\n\nfor input, output in data:\n    def closure():\n        loss = loss_function(output, model(input))\n        loss.backward()\n        return loss\n\n    # 单次调用完成两步操作\n    optimizer.step(closure)\n    optimizer.zero_grad()\n```\n\n### 关键注意事项\n\n*   **批归一化 (Batch Normalization)**: \n    由于进行了两次前向传播，BN 层的运行统计量会被计算两次，这可能导致问题。建议在第二次前向传播时禁用运行统计量的更新。\n    \n    ```python\n    # 第一次传播：启用统计量更新\n    enable_running_stats(model) \n    loss = loss_function(output, model(input))\n    loss.backward()\n    optimizer.first_step(zero_grad=True)\n\n    # 第二次传播：禁用统计量更新\n    disable_running_stats(model)\n    loss_function(output, model(input)).backward()\n    optimizer.second_step(zero_grad=True)\n    ```\n\n*   **多 GPU 训练**: \n    如果在多卡环境下训练，需在第一次反向传播时使用 `no_sync()` 上下文管理器，以避免梯度在不同卡之间过早同步。\n\n    ```python\n    with model.no_sync():\n        loss.backward()\n    optimizer.first_step(zero_grad=True)\n    ```\n\n*   **学习率调度**: \n    学习率调度器应绑定到 `base_optimizer` 上，而不是 SAM 包装器本身。\n    ```python\n    scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer.base_optimizer, T_max=200)\n    ```\n\n*   **ASAM (自适应版本)**: \n    若启用 `adaptive=True`，建议将 `rho` 参数调大至约 2.0（原文建议比标准 SAM 大 10 倍左右），通常能获得更好的效果。","某医疗影像初创团队正在训练一个基于 ResNet 的肺炎检测模型，旨在提升模型在未知医院数据上的泛化能力。\n\n### 没有 sam 时\n- 模型在内部测试集上准确率高达 98%，但部署到合作医院的真实数据时，性能骤降至 82%，出现严重的过拟合现象。\n- 损失函数收敛到了尖锐的局部极小值（Sharp Minimum），导致参数对输入数据的微小扰动极其敏感，鲁棒性差。\n- 面对医疗标注中不可避免的噪声（如医生判断差异），模型容易强行记忆错误标签，难以学习到真正的病理特征。\n- 为了缓解泛化问题，工程师不得不花费大量时间手动调整学习率、增加 Dropout 比例或引入复杂的数据增强策略，调参成本极高。\n\n### 使用 sam 后\n- 模型主动寻找“平坦”的损失最小值区域（Flat Minimum），在未见过的医院数据上准确率稳定在 94%，泛化差距显著缩小。\n- 通过同时最小化损失值及其锐度，模型参数位于低损失的邻域内，对数据噪声和分布偏移表现出极强的抵抗力。\n- 即使训练数据包含约 15% 的误标样本，sam 也能有效抑制模型对噪声的过拟合，表现媲美专门针对噪声标签设计的算法。\n- 无需繁琐的额外正则化技巧，仅需将优化器替换为 sam 包装器（配合 SGD），即可在两次前向传播的计算代价下获得 State-of-the-Art 的性能。\n\nsam 通过引导模型收敛至更平坦的最优解，以微小的计算开销换取了显著的泛化提升和抗噪鲁棒性，是解决深度学习模型“落地难”问题的关键利器。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fdavda54_sam_ddc2182b.png","davda54","David Samuel","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Fdavda54_9e1e54d1.jpg","PhD student at University of Oslo, Language Technology Group","LTG, UiO","Oslo, Norway","david.samuel@seznam.cz","davidsamuelcz","https:\u002F\u002Fwww.mn.uio.no\u002Fifi\u002Fenglish\u002Fpeople\u002Faca\u002Fdavisamu\u002Findex.html","https:\u002F\u002Fgithub.com\u002Fdavda54",[83],{"name":84,"color":85,"percentage":86},"Python","#3572A5",100,1969,213,"2026-04-07T06:32:58","MIT",1,"","未说明（支持多 GPU 并行训练，需使用 model.no_sync() 处理梯度同步）","未说明",{"notes":96,"python":94,"dependencies":97},"该工具是 PyTorch 优化器的轻量级封装（非官方实现），用于锐度感知最小化（SAM\u002FASAM）。主要特点：1. 训练速度约为普通优化的两倍，因为每个步骤需要两次前向 - 后向传播；2. 若使用批量归一化（BatchNorm），建议在第二次前向传播时禁用运行统计量更新（通过设置 BN momentum 为 0 或使用提供的 enable\u002Fdisable_running_stats 辅助函数）；3. 自适应 SAM (ASAM) 建议使用比原始 SAM 大得多的 rho 值（约 10 倍，如 rho=2.0）；4. 学习率调度器应应用于 base_optimizer 或使用基于 closure 的单步调用模式。",[98],"torch",[14],[101,102,64,103],"optimizer","pytorch","sharpness-aware",null,"2026-03-27T02:49:30.150509","2026-04-11T03:23:10.662501",[108,113,118,123,128,132],{"id":109,"question_zh":110,"answer_zh":111,"source_url":112},28828,"SAM 是否支持使用 FP16（混合精度训练）进行加速训练？如果遇到 NaN 损失该如何解决？","SAM 可以与支持自动混合精度（AMP）的代码配合使用。关键在于确保在第一次和第二次前向传播时都正确使用了 `torch.cuda.amp.autocast()` 上下文管理器。以下是一个可行的实现示例：\n\n```python\n# 第一次前向 - 反向传播\nwith torch.cuda.amp.autocast():\n    preds_first = model(images)\n    loss = criterion(preds_first, labels)\nloss.mean().backward()\noptimizer.first_step(zero_grad=True)\n\n# 第二次前向 - 反向传播\nwith torch.cuda.amp.autocast():\n    preds_second = model(images)\n    loss_second = criterion(preds_second, labels)\nloss_second.mean().backward()\noptimizer.second_step(zero_grad=True)\n```\n如果切换回 FP32 训练正常，请检查是否在两次 forward pass 中都正确启用了 autocast。","https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam\u002Fissues\u002F7",{"id":114,"question_zh":115,"answer_zh":116,"source_url":117},28829,"在 SAM 训练中如何正确处理 BatchNorm（批归一化），以避免模型不收敛？","在 SAM 的第二步（扰动点）中，不应更新 BatchNorm 的统计量（running_mean 和 running_var），但必须保持其可学习参数（gamma\u002Fweight 和 beta\u002Fbias）处于可更新状态并与网络其他参数对齐。\n\n常见的错误做法是直接调用 `model.eval()` 或 `bn.eval()`，这会冻结所有参数（包括 gamma 和 beta），导致它们与其他参数发散，最终引起梯度爆炸或损失为 NaN。\n\n推荐的解决方案是自定义函数，仅将 BatchNorm 模块设置为 eval 模式以冻结统计量，而不影响整体训练流程或其他层（如 Dropout）：\n\n```python\ndef disable_bn(net):\n    \"\"\"将网络中的 BatchNorm 模块设置为推理模式，冻结运行统计量，但不冻结权重。\"\"\"\n    for module in net.modules():\n        if isinstance(module, (nn.BatchNorm1d, nn.BatchNorm2d, nn.BatchNorm3d)):\n            module.eval()\n\ndef enable_bn(net):\n    \"\"\"将网络中的 BatchNorm 模块重新设置为训练模式。\"\"\"\n    for module in net.modules():\n        if isinstance(module, (nn.BatchNorm1d, nn.BatchNorm2d, nn.BatchNorm3d)):\n            module.train()\n```\n在训练循环中：第一步调用 `enable_bn` 更新统计量；第二步调用 `disable_bn` 防止统计量被扰动数据污染。","https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam\u002Fissues\u002F30",{"id":119,"question_zh":120,"answer_zh":121,"source_url":122},28830,"SAM 的两次前向传播会导致 BatchNorm 的 running mean\u002Fvar 被计算两次吗？这是否与官方实现不一致？","是的，标准实现中两次前向传播确实会更新两次统计量。虽然 Google 的 JAX 实现通过保存中间状态（inner_state）只计算一次，但在 PyTorch 中直接模拟较复杂。\n\n维护者指出，最简单的替代方案是在第二次前向传播前调用 `model.eval()`，但这有一个副作用：它会同时关闭 Dropout 层，而不仅仅是冻结 BatchNorm 的统计量。\n\n因此，更精细的做法是使用自定义的 `disable_bn` 函数（见上一条 FAQ），仅针对 BatchNorm 层调用 `.eval()`，从而在冻结统计量的同时保留 Dropout 的训练行为。至于是否必须完全复现“只计算一次统计量”的行为，取决于具体任务，通常上述自定义开关 BN 的方法已能取得良好效果。","https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam\u002Fissues\u002F17",{"id":124,"question_zh":125,"answer_zh":126,"source_url":127},28831,"如何在代码中实现自适应锐度感知最小化（ASAM）？","ASAM 是 SAM 的改进版，引入了尺度不变性。实现的核心在于修改 epsilon 的计算方式，引入算子 $T_w$（通常与权重的绝对值相关）。\n\n根据社区讨论，一种可行的实现思路是在计算梯度范数（norm）和 epsilon 时，逐元素地乘以权重的绝对值。参考代码如下：\n\n1. 计算加权后的梯度范数：\n```python\nnorm = torch.norm(\n    torch.stack([\n        (torch.abs(p) * p.grad).norm(p=2).to(shared_device)\n        for group in self.param_groups \n        for p in group[\"params\"]\n        if p.grad is not None\n    ]),\n    p=2\n)\n```\n\n2. 计算扰动量 epsilon：\n```python\ne_w = torch.pow(p, 2) * p.grad * scale.to(p)\n# 或者根据论文公式调整，通常涉及 abs(p) 的乘法操作\n```\n\n维护者确认这种“为每一层或每个参数使用独立范数”的思路是合理的，尤其对于大模型，且实验结果显示其能带来边际性能提升并进一步防止过拟合。","https:\u002F\u002Fgithub.com\u002Fdavda54\u002Fsam\u002Fissues\u002F22",{"id":129,"question_zh":130,"answer_zh":131,"source_url":127},28832,"SAM 中的梯度范数（norm）应该是基于整个模型的所有梯度计算，还是应该针对每个权重单独计算？","这是一个关于实现细节的重要讨论点。原始论文公式似乎暗示使用整个模型梯度的全局范数来计算 epsilon。\n\n然而，有用户指出，如果计算所有梯度的全局范数，少数参数的大梯度可能会压缩其他所有参数的 epsilon 值，这是不理想的。从直觉和图示来看，每个权重应该仅基于其自身的梯度范数来确定扰动大小。\n\n虽然原始代码使用了全局范数，但社区倾向于认为按层或按参数单独计算范数（如 ASAM 中的做法）可能更合理，特别是对于大型模型。如果您发现训练不稳定或某些层更新受阻，可以尝试修改代码，对每个参数组或每个参数单独计算范数后再应用扰动。",{"id":133,"question_zh":134,"answer_zh":135,"source_url":117},28833,"为什么在 SAM 第二步使用 `model.eval()` 会导致梯度范数爆炸或 Loss 变为 NaN？","这是因为 `model.eval()` 不仅会冻结 BatchNorm 的 running_mean 和 running_var，还会冻结 BatchNorm 中的可学习参数 gamma（weight）和 beta（bias）。\n\n在训练过程中，gamma 和 beta 需要像其他网络参数一样不断更新，以保持与网络其他部分的对齐。如果在 SAM 的扰动步骤中使用 `model.eval()` 冻结了它们，随着迭代次数增加，这些参数会与未冻结的参数产生发散（divergence）。这种发散在初期可能不明显，但累积后会导致梯度计算异常，进而引发梯度范数爆炸或 Loss 变为 NaN。\n\n解决方法是不要对整个模型调用 `eval()`，而是仅遍历网络模块，单独对 BatchNorm 层调用 `.eval()`（冻结统计量），同时确保这些层的 `.train()` 状态在其他时候能被正确恢复，或者使用专门编写的 `disable_bn` 辅助函数来精确控制行为。",[]]