pytorch-styleguide

GitHub
2k 177 非常简单 1 次阅读 3天前GPL-3.0开发框架
AI 解读 由 AI 自动生成,仅供参考

pytorch-styleguide 是一份非官方的 PyTorch 风格指南与最佳实践汇总,旨在帮助开发者编写更清晰、规范且高效的深度学习代码。它凝聚了作者团队在科研与创业项目中积累的一年多实战经验,系统梳理了从 Python 基础规范到 PyTorch 高级用法的完整流程。

许多开发者在使用 PyTorch 时往往缺乏统一的代码规范,导致项目难以维护或协作效率低下。pytorch-styleguide 通过提供明确的命名约定、推荐的 Python 3.6+ 新特性(如类型提示与 f-string),以及 Google Python 风格指南的精简版,有效解决了代码风格混乱的问题。此外,它还详细对比了 Jupyter Notebook 与 Python 脚本的适用场景,并提供了 VS Code 和 PyCharm 连接远程服务器的配置教程,极大优化了本地开发、远程调试的工作流。

这份指南特别适合从事深度学习的研究人员、算法工程师以及初创团队使用。其独特亮点在于不仅涵盖理论规范,还分享了来自 Lightly 项目的实用代码片段,包括自注意力机制、感知损失、谱归一化等常见模块的实现方案,并附带完整的 CIFAR-10 模型训练示例。无论你是希望提升代码质量的新手,还是寻求工作流优化的资深从业者,pytorch-styleguide 都能为你提供极具价值的参考。

使用场景

某初创公司算法团队在开发基于 PyTorch 的图像识别模型时,面临多人协作代码风格混乱及远程调试效率低下的挑战。

没有 pytorch-styleguide 时

  • 团队成员命名习惯各异,常量、类与函数混用大小写,导致新成员阅读 DataLoaderbatch_size 等变量时频繁产生歧义。
  • 缺乏统一的 Python 版本与类型提示规范,代码中充满隐式类型错误,重构时极易引发难以追踪的 Bug。
  • 本地开发与远程 GPU 服务器环境割裂,手动同步代码和配置虚拟环境耗时费力,调试过程如同“盲人摸象”。
  • 常用模块(如自注意力机制、感知损失)重复造轮子,且实现质量参差不齐,严重拖慢实验迭代速度。
  • 过度依赖 Jupyter Notebook 进行最终模型训练,导致代码逻辑分散,难以版本控制和工程化部署。

使用 pytorch-styleguide 后

  • 遵循 Google 风格指南统一命名规范,代码结构清晰一致,任何成员都能快速理解并接手他人的 visualize_tensor 等函数。
  • 强制采用 Python 3.6+ 及静态类型检查,结合 f-string 提升代码简洁度,显著减少了运行时类型错误。
  • 利用指南推荐的 VS Code Remote-SSH 配置,实现本地编写代码、远程无缝调试与自动环境同步,开发体验如履平地。
  • 直接复用指南中经过验证的构建块(如 Spectral Normalization、Adaptive Instance Normalization),大幅缩短模型搭建周期。
  • 明确区分 Notebook 用于探索、Python 脚本用于生产,配合标准化项目结构,使模型训练流程更稳健且易于维护。

pytorch-styleguide 通过确立最佳实践标准,将团队从琐碎的代码规范与环境配置中解放出来,使其能专注于核心算法创新。

运行环境要求

操作系统
  • 未说明
GPU

未说明

内存

未说明

依赖
notes本文档主要是一份 PyTorch 最佳实践和代码风格指南,而非具有严格运行环境依赖的可执行软件包。文中建议使用 VS Code 或 PyCharm 作为开发工具,并支持通过 SSH 连接远程机器(如 AWS、Google Cloud)进行开发。推荐使用 Jupyter Notebook 进行初步探索,正式训练时转为 Python 脚本以确保可复现性。文档包含 CIFAR-10 的训练示例及多种网络构建块(如自注意力、感知损失等)的代码片段。
python3.6+
torch
torchvision
Pillow
numpy
prefetch_generator
tqdm
torchinfo
pytorch-styleguide hero image

快速开始

PyTorch 工具、最佳实践与风格指南

这不是 PyTorch 的官方风格指南。本文档总结了我们使用 PyTorch 框架进行深度学习一年多以来的最佳实践。请注意,我们分享的经验主要来自研究和初创公司的视角。

这是一个开放项目,欢迎其他贡献者编辑和改进本文档。

您将在这份文档中找到三个主要部分。首先是对 Python 最佳实践的快速回顾,接着是一些使用 PyTorch 的技巧和建议。最后,我们将分享一些使用其他框架的见解和经验,这些帮助我们整体上提升了工作流程。

更新 2020年12月20日

  • 添加了一个在 cifar10 数据集上训练模型的完整示例
  • 增加了使用 VS Code 和远程扩展的设置指南

更新 2019年4月30日

在收到大量积极反馈后,我还添加了我们在 Lightly 项目中常用的一些构建模块的摘要: 您将找到用于(自注意力机制、基于 VGG 的感知损失、谱归一化、自适应实例归一化等)的构建模块。
损失函数、层及其他构建模块的代码片段

我们推荐使用 Python 3.6+

根据我们的经验,我们建议使用 Python 3.6 或更高版本,因为以下特性对编写整洁简洁的代码非常有帮助:

Python 风格指南回顾

我们尽量遵循 Google 的 Python 风格指南。 请参考 Google 提供的、文档完善的 Python 代码风格指南

在此我们提供最常用规则的摘要:

命名规范

摘自 3.16.4

类型 规范 示例
包与模块 小写加下划线 from prefetch_generator import BackgroundGenerator
首字母大写 class DataLoader
常量 全大写加下划线 BATCH_SIZE=16
实例 小写加下划线 dataset = Dataset
方法与函数 小写加下划线() def visualize_tensor()
变量 小写加下划线 background_color='Blue'

IDEs

代码编辑器

一般来说,我们推荐使用像 Visual Studio Code 或 PyCharm 这样的 IDE。虽然 VS Code 是一个相对轻量级的编辑器,却提供了语法高亮和自动补全功能,而 PyCharm 则拥有许多用于处理远程集群的高级特性。 VS Code 凭借其快速增长的扩展生态系统,已经变得非常强大。

使用远程机器设置 Visual Studio Code

请确保已安装以下扩展:

  • Python(语法检查、自动补全、语法高亮、代码格式化)
  • Remote - SSH(用于连接远程机器)
  1. 按照此处的指南操作:https://code.visualstudio.com/docs/remote/remote-overview

设置 PyCharm 以连接远程机器

  1. 登录到您的远程机器(AWS、Google 等)。
  2. 创建一个新的文件夹和一个新的虚拟环境。
  3. 在 PyCharm(专业版)的项目设置中配置远程解释器。
  4. 配置远程 Python 解释器(指向 AWS、Google 等上的虚拟环境路径)。
  5. 配置本地代码与远程机器之间的映射关系。

如果设置正确,这将使您能够做到以下几点:

  • 在本地计算机上编写代码(笔记本电脑、台式机),无论您身在何处(离线或在线)。
  • 将本地代码同步到远程机器。
  • 额外的包会自动安装在远程机器上。
  • 您无需在本地机器上存储任何数据集。
  • 在远程机器上运行和调试代码,就像在本地机器上运行一样。

Jupyter Notebook 与 Python 脚本

一般来说,我们建议在初步探索或尝试新模型和代码时使用 Jupyter Notebook。 一旦您需要在更大的数据集上训练模型,并且更注重可重复性时,则应使用 Python 脚本。

我们推荐的工作流程:

  1. 从 Jupyter Notebook 开始。
  2. 探索数据和模型。
  3. 在 Notebook 的单元格中构建类和方法。
  4. 将代码迁移到 Python 脚本中。
  5. 在服务器上进行训练或部署。
Jupyter Notebook Python 脚本
+ 适合探索 + 可以长时间运行任务而不中断
+ 方便调试 + 易于通过 git 跟踪更改
- 容易变成超大文件 - 调试通常意味着重新运行整个脚本
- 可能会被中断(不适合长时间训练)
- 容易出错并变得混乱

常用库:

名称 描述 用途
torch 用于神经网络的基础框架 创建张量、构建网络并使用反向传播进行训练
torchvision PyTorch 计算机视觉模块 图像数据预处理、增强和后处理
Pillow (PIL) Python 图像处理库 加载和保存图像
Numpy 用于科学计算的 Python 库 数据的预处理和后处理
prefetch_generator 后台处理库 在计算过程中后台加载下一批数据
tqdm 进度条 每个 epoch 训练过程中的进度显示
torchinfo 为 PyTorch 提供类似 Keras 的模型摘要 显示网络结构、各层参数及尺寸
torch.utils.tensorboard PyTorch 内置 TensorBoard 记录实验并在 TensorBoard 中可视化

文件组织

不要把所有的层和模型都放在同一个文件里。最佳实践是将最终的网络单独放在一个文件中(例如 networks.py),并将层、损失函数和操作分别放在各自的文件中(layers.py、losses.py、ops.py)。完成的模型(由一个或多个网络组成)应在以其命名的文件中被引用(如 yolov3.py、DCGAN.py)。

主程序以及训练和测试脚本只应从包含模型名称的文件中导入内容。

在 PyTorch 中构建神经网络

我们建议将网络拆分为较小的可重用组件。一个网络是一个 nn.Module,由操作或其他 nn.Module 作为构建块组成。损失函数也是 nn.Module,因此可以直接集成到网络中。

继承自 nn.Module 的类必须有一个 forward 方法,用于实现相应层或操作的前向传播。

可以使用 self.net(input) 将一个 nn.module 应用于输入数据。这实际上就是调用该对象的 call() 方法,将输入通过模块传递。

output = self.net(input)

PyTorch 中的一个简单网络

对于只有一个输入和一个输出的简单网络,可以使用以下模式:

class ConvBlock(nn.Module):
    def __init__(self):
        super(ConvBlock, self).__init__()
        self.block = nn.Sequential(
            nn.Conv2d(...), 
            nn.ReLU(), 
            nn.BatchNorm2d(...)
        )  
    
    def forward(self, x):
        return self.block(x)

class SimpleNetwork(nn.Module):
    def __init__(self, num_resnet_blocks=6):
        super(SimpleNetwork, self).__init__()
        # 在这里添加各个层
        layers = [ConvBlock(...)]
        for i in range(num_resnet_blocks):
            layers += [ResBlock(...)]
        self.net = nn.Sequential(*layers)
    
    def forward(self, x):
        return self.net(x)

请注意以下几点:

  • 我们重复使用简单的、可重复的构建块,例如 ConvBlock,它由相同的循环模式(卷积、激活、归一化)组成,并将其放入一个单独的 nn.Module 中。
  • 我们构建一个所需层的列表,最后使用 nn.Sequential() 将其转换为模型。我们在列表对象前使用 * 操作符来解包列表。
  • 在前向传播中,我们只需将输入通过模型即可。

在 PyTorch 中具有跳跃连接的网络

class ResnetBlock(nn.Module):
    def __init__(self, dim, padding_type, norm_layer, use_dropout, use_bias):
        super(ResnetBlock, self).__init__()
        self.conv_block = self.build_conv_block(...)

    def build_conv_block(self, ...):
        conv_block = []

        conv_block += [nn.Conv2d(...),
                       norm_layer(...),
                       nn.ReLU()]
        if use_dropout:
            conv_block += [nn.Dropout(...)]
            
        conv_block += [nn.Conv2d(...),
                       norm_layer(...)]

        return nn.Sequential(*conv_block)

    def forward(self, x):
        out = x + self.conv_block(x)
        return out

在这里,ResNet 块的跳跃连接直接在前向传播中实现。PyTorch 允许在前向传播过程中进行动态操作。

在 PyTorch 中具有多个输出的网络

对于需要多个输出的网络,例如使用预训练的 VGG 网络构建感知损失时,可以使用以下模式:

class Vgg19(nn.Module):
  def __init__(self, requires_grad=False):
    super(Vgg19, self).__init__()
    vgg_pretrained_features = models.vgg19(pretrained=True).features
    self.slice1 = torch.nn.Sequential()
    self.slice2 = torch.nn.Sequential()
    self.slice3 = torch.nn.Sequential()

    for x in range(7):
        self.slice1.add_module(str(x), vgg_pretrained_features[x])
    for x in range(7, 21):
        self.slice2.add_module(str(x), vgg_pretrained_features[x])
    for x in range(21, 30):
        self.slice3.add_module(str(x), vgg_pretrained_features[x])
    if not requires_grad:
        for param in self.parameters():
            param.requires_grad = False

  def forward(self, x):
    h_relu1 = self.slice1(x)
    h_relu2 = self.slice2(h_relu1)        
    h_relu3 = self.slice3(h_relu2)        
    out = [h_relu1, h_relu2, h_relu3]
    return out

请注意以下几点:

  • 我们使用了 torchvision 提供的预训练模型。
  • 我们将网络拆分为三个切片。每个切片由预训练模型中的层组成。
  • 我们通过设置 requires_grad = False 来“冻结”网络。
  • 我们返回一个包含三个切片输出的列表。

自定义损失函数

即使 PyTorch 已经提供了许多标准损失函数,有时仍然可能需要创建自己的损失函数。为此,可以创建一个单独的文件 losses.py,并扩展 nn.Module 类来创建自定义损失函数:

class CustomLoss(nn.Module):
    
    def __init__(self):
        super(CustomLoss,self).__init__()
        
    def forward(self,x,y):
        loss = torch.mean((x - y)**2)
        return loss

训练模型的推荐代码结构

完整的示例可以在本仓库的 cifar10-example 文件夹中找到。

请注意,我们使用了以下模式:

  • 我们使用 prefetch_generator 中的 BackgroundGenerator 在后台加载下一个批次 更多信息请参见此问题
  • 我们使用 tqdm 监控训练进度并显示“计算效率”。这有助于我们找到数据加载管道中的瓶颈。
# 导入语句
import torch
import torch.nn as nn
from torch.utils import data
...

# 设置标志/种子
torch.backends.cudnn.benchmark = True
np.random.seed(1)
torch.manual_seed(1)
torch.cuda.manual_seed(1)
...

# 从主代码开始
if __name__ == '__main__':
    # 使用 argparse 处理实验的额外参数
    parser = argparse.ArgumentParser(description="训练一个用于...的网络")
    ...
    opt = parser.parse_args() 
    
    # 添加数据集相关代码(我们通常使用训练集和验证/测试集)
    data_transforms = transforms.Compose([
        transforms.Resize((opt.img_size, opt.img_size)),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
    ])
    
    train_dataset = datasets.ImageFolder(
        root=os.path.join(opt.path_to_data, "train"),
        transform=data_transforms)
    train_data_loader = data.DataLoader(train_dataset, ...)
    
    test_dataset = datasets.ImageFolder(
        root=os.path.join(opt.path_to_data, "test"),
        transform=data_transforms)
    test_data_loader = data.DataLoader(test_dataset ...)
    ...
    
    # 实例化网络(已从 *networks.py* 中导入)
    net = MyNetwork(...)
    ...
    
    # 创建损失函数(PyTorch 中的 criterion)
    criterion_L1 = torch.nn.L1Loss()
    ...
    
    # 如果在 GPU 上运行且希望使用 CUDA,则将模型移动到 GPU
    use_cuda = torch.cuda.is_available()
    if use_cuda:
        net = net.cuda()
        ...
    
    # 创建优化器
    optim = torch.optim.Adam(net.parameters(), lr=opt.lr)
    ...
    
    # 如果需要或希望,加载检查点
    start_n_iter = 0
    start_epoch = 0
    if opt.resume:
        ckpt = load_checkpoint(opt.path_to_checkpoint) # 自定义方法,用于加载上次的检查点
        net.load_state_dict(ckpt['net'])
        start_epoch = ckpt['epoch']
        start_n_iter = ckpt['n_iter']
        optim.load_state_dict(ckpt['optim'])
        print("已恢复上次的检查点")
        ...
        
    # 如果希望在多个 GPU 上运行实验,则将模型转移到这些 GPU 上
    net = torch.nn.DataParallel(net)
    ...
    
    # 通常我们会使用 tensorboardX 来跟踪实验过程
    writer = SummaryWriter(...)
    
    # 现在开始主循环
    n_iter = start_n_iter
    for epoch in range(start_epoch, opt.epochs):
        # 将模型设置为训练模式
        net.train()
        ...
        
        # 使用 prefetch_generator 和 tqdm 遍历数据
        pbar = tqdm(enumerate(BackgroundGenerator(train_data_loader, ...)),
                    total=len(train_data_loader))
        start_time = time.time()
        
        # 遍历数据集的循环
        for i, data in pbar:
            # 数据准备
            img, label = data
            if use_cuda:
                img = img.cuda()
                label = label.cuda()
            ...
            
            # 使用 tqdm 跟踪数据准备时间和计算时间是非常好的做法,这样可以发现数据加载器中的问题
            prepare_time = start_time-time.time()
            
            # 前向传播和反向传播
            optim.zero_grad()
            ...
            loss.backward()
            optim.step()
            ...
            
            # 更新 tensorboardX
            writer.add_scalar(..., n_iter)
            ...
            
            # 计算计算时间和 *计算效率*
            process_time = start_time-time.time()-prepare_time
            pbar.set_description("计算效率: {:.2f}, 第 {}/{} 个 epoch:".format(
                process_time/(process_time+prepare_time), epoch, opt.epochs))
            start_time = time.time()
            
        # 可以每隔 x 个 epoch 进行一次测试
        if epoch % x == x-1:
            # 将模型切换到评估模式
            net.eval()
            ...
            # 进行一些测试
            pbar = tqdm(enumerate(BackgroundGenerator(test_data_loader, ...)),
                    total=len(test_data_loader)) 
            for i, data in pbar:
                ...
                
            # 如果需要,保存检查点
            ...

在 PyTorch 中使用多 GPU 进行训练

在 PyTorch 中有两种不同的模式可用于多 GPU 训练。 根据我们的经验,这两种模式都是可行的。不过第一种方式更简洁、代码量更少。第二种方式由于 GPU 之间的通信较少,性能上略有优势。关于这两种方法的讨论,请参阅 PyTorch 官方论坛

将每个网络的批量输入拆分

最常见的方式是将所有 网络 的批次简单地分配到各个 GPU 上。

例如,如果一个模型在单个 GPU 上以 64 的批量大小运行,那么在两个 GPU 上运行时,每个 GPU 的批量大小则为 32。这可以通过用 nn.DataParallel(model) 包装模型来自动完成。

将所有网络打包成一个“超级”网络,并拆分输入批次

这种模式相对较少使用。NVIDIA 的 pix2pixHD 实现 就是一个采用这种方法的仓库。

应该做的和不应该做的

避免在 nn.Module 的前向传播方法中使用 NumPy 代码

NumPy 是在 CPU 上运行的,速度比 PyTorch 代码慢。由于 PyTorch 在设计时就考虑了与 NumPy 的相似性,因此大多数 NumPy 函数都已经在 PyTorch 中得到了支持。

将数据加载器与主代码分离

数据加载流程应独立于主训练代码。PyTorch 使用后台工作线程来更高效地加载数据,同时不会干扰主训练过程。

不要在每一步都记录结果

通常我们的模型会训练数千步。因此,只需每隔几步记录一次损失和其他结果即可,这样可以减少开销。尤其是在训练过程中,保存中间结果图像可能会非常耗时。

使用命令行参数

使用命令行参数来设置代码执行期间的参数(如批量大小、学习率等)非常方便。一种简单的方法是打印从 parse_args 接收到的参数字典,以便跟踪实验参数:

...
# 将参数保存到 config.txt 文件
opt = parser.parse_args()
with open("config.txt", "w") as f:
    f.write(opt.__str__())
...

尽可能使用 .detach() 从计算图中释放张量

PyTorch 会跟踪所有涉及张量的操作以实现自动微分。使用 .detach() 可以避免记录不必要的操作。

打印标量张量时使用 .item()

可以直接打印变量,但建议使用 variable.detach()variable.item()。在 PyTorch 0.4 之前的版本中,需要使用 .data 来访问变量的张量。

nn.Module 上使用 call 方法而不是 forward 方法

这两种方法并不完全相同,正如其中一个议题所指出的那样 这里

output = self.net.forward(input)

# 它们不相等!
output = self.net(input)

常见问题解答

  1. 如何确保我的实验可复现?

我们建议在代码开头设置以下随机种子:

np.random.seed(1)
torch.manual_seed(1)
torch.cuda.manual_seed(1)
  1. 如何进一步提升训练和推理速度?

在 Nvidia GPU 上,您可以在代码开头添加以下一行。这将使 CUDA 后端在首次执行时优化您的计算图。但请注意,如果更改了网络的输入或输出张量大小,每次发生改变时都会重新优化计算图。这可能导致运行速度非常慢,并出现内存不足错误。只有当您的输入和输出始终保持相同形状时,才应启用此标志。通常情况下,这会带来约 20% 的性能提升。

torch.backends.cudnn.benchmark = True
  1. 使用 tqdm + prefetch_generator 模式时,计算效率的理想值是多少?

这取决于所使用的机器、预处理流水线以及网络规模。在配备 1080Ti GPU 和 SSD 的设备上,我们观察到接近 1.0 的计算效率,这是理想情况。如果使用较浅(较小)的网络或速度较慢的硬盘,该数值可能会降至 0.1–0.2 左右,具体取决于您的配置。

  1. 如果显存不足,如何实现批量大小大于 1? 在 PyTorch 中,我们可以非常容易地实现虚拟批量大小。只需阻止优化器更新参数,并在 batch_size 次循环中累计梯度即可。
...
# 在主循环中
out = net(input)
loss = criterion(out, label)
# 只调用 backward 累计梯度,但不在此处执行 step
loss.backward() 
total_loss += loss.item() / batch_size
if n_iter % batch_size == batch_size-1:
    # 此处使用虚拟批量大小执行优化步骤
    optim.step()
    optim.zero_grad()
    print('总损失:', total_loss)
    total_loss = 0.0
...
  1. 如何在训练过程中调整学习率?

我们可以直接通过实例化的优化器访问学习率,如下所示:

...
for param_group in optim.param_groups:
    old_lr = param_group['lr']
    new_lr = old_lr * 0.1
    param_group['lr'] = new_lr
    print('学习率从 {} 调整为 {}'.format(old_lr, new_lr))
...
  1. 如何在训练过程中将预训练模型用作损失函数(不进行反向传播)?

如果您希望使用 VGG 等预训练模型来计算损失,但不对其进行训练(例如,在风格迁移、GAN 或自编码器中使用的感知损失),可以采用以下模式:

...
# 实例化模型
pretrained_VGG = VGG19(...)

# 禁用梯度(防止训练)
for p in pretrained_VGG.parameters():  # 将 requires_grad 重置为 False
    p.requires_grad = False
...
# 不必使用 no_grad() 上下文管理器,直接运行模型即可
# VGG 模型不会计算任何梯度
out_real = pretrained_VGG(input_a)
out_fake = pretrained_VGG(input_b)
loss = any_criterion(out_real, out_fake)
...
  1. 为什么在 PyTorch 中要使用 .train() 和 .eval() 方法?

这些方法用于将 BatchNorm2dDropout2d 等层从训练模式切换到推理模式。所有继承自 nn.Module 的模块都具有一个名为 isTraining 的属性。.eval().train() 只是简单地将该属性设置为 True/False。有关此方法实现的更多信息,请参阅 PyTorch 源码中的模块部分

  1. 我的模型在推理时占用大量内存。如何在 PyTorch 中正确地进行推理? 请确保在代码执行过程中不计算和存储任何梯度。您可以使用以下模式来保证这一点:
with torch.no_grad():
    # 在此处运行模型
    out_tensor = net(in_tensor)
  1. 如何对预训练模型进行微调?

在 PyTorch 中,您可以冻结某些层,从而阻止它们在优化步骤中被更新。


# 您可以通过以下方式冻结整个模块:
for p in pretrained_VGG.parameters():  # 将 requires_grad 重置为 False
    p.requires_grad = False
  1. 何时使用 Variable(...)

自 PyTorch 0.4 版本起,VariableTensor 已经合并。我们不再需要显式创建 Variable 对象。

  1. 使用 C++ 编写的 PyTorch 是否比 Python 版本更快? C++ 版本大约快 10%
  2. TorchScript / JIT 能否加速我的代码?

待办……

  1. 使用 cudnn.benchmark=True 的 PyTorch 代码是否更快? 根据我们的经验,可以提升约 20% 的速度。不过,首次运行模型时,构建优化后的计算图需要较长时间。在某些情况下(前向传播中存在循环、输入形状不固定、前向传播中包含 if/else 等),此标志可能会导致“内存不足”或其他错误。
  2. 如何使用多块 GPU 进行训练?

待办……

  1. PyTorch 中的 .detach() 是如何工作的? 它会将张量从计算图中分离出来。一个很好的示意图可以在这里找到:http://www.bnikolic.co.uk/blog/pytorch-detach.html

您喜欢这个仓库吗?

请提供反馈,帮助我们改进这份风格指南!您可以开一个 issue,或者通过创建 pull request 提出修改建议。

如果您喜欢这个仓库,别忘了查看我们提供的其他框架:

相似工具推荐

openclaw

OpenClaw 是一款专为个人打造的本地化 AI 助手,旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚,能够直接接入你日常使用的各类通讯渠道,包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息,OpenClaw 都能即时响应,甚至支持在 macOS、iOS 和 Android 设备上进行语音交互,并提供实时的画布渲染功能供你操控。 这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地,用户无需依赖云端服务即可享受快速、私密的智能辅助,真正实现了“你的数据,你做主”。其独特的技术亮点在于强大的网关架构,将控制平面与核心助手分离,确保跨平台通信的流畅性与扩展性。 OpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者,以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力(支持 macOS、Linux 及 Windows WSL2),即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你

349.3k|★★★☆☆|1周前
Agent开发框架图像

stable-diffusion-webui

stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。

162.1k|★★★☆☆|1周前
开发框架图像Agent

everything-claude-code

everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上

159.6k|★★☆☆☆|今天
开发框架Agent语言模型

ComfyUI

ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。

108.3k|★★☆☆☆|1周前
开发框架图像Agent

gemini-cli

gemini-cli 是一款由谷歌推出的开源 AI 命令行工具,它将强大的 Gemini 大模型能力直接集成到用户的终端环境中。对于习惯在命令行工作的开发者而言,它提供了一条从输入提示词到获取模型响应的最短路径,无需切换窗口即可享受智能辅助。 这款工具主要解决了开发过程中频繁上下文切换的痛点,让用户能在熟悉的终端界面内直接完成代码理解、生成、调试以及自动化运维任务。无论是查询大型代码库、根据草图生成应用,还是执行复杂的 Git 操作,gemini-cli 都能通过自然语言指令高效处理。 它特别适合广大软件工程师、DevOps 人员及技术研究人员使用。其核心亮点包括支持高达 100 万 token 的超长上下文窗口,具备出色的逻辑推理能力;内置 Google 搜索、文件操作及 Shell 命令执行等实用工具;更独特的是,它支持 MCP(模型上下文协议),允许用户灵活扩展自定义集成,连接如图像生成等外部能力。此外,个人谷歌账号即可享受免费的额度支持,且项目基于 Apache 2.0 协议完全开源,是提升终端工作效率的理想助手。

100.8k|★★☆☆☆|1周前
插件Agent图像

markitdown

MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具,专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片(含 OCR)、音频(含语音转录)、HTML 乃至 YouTube 链接等多种格式的解析,能够精准提取文档中的标题、列表、表格和链接等关键结构信息。 在人工智能应用日益普及的今天,大语言模型(LLM)虽擅长处理文本,却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点,它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式,成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外,它还提供了 MCP(模型上下文协议)服务器,可无缝集成到 Claude Desktop 等 LLM 应用中。 这款工具特别适合开发者、数据科学家及 AI 研究人员使用,尤其是那些需要构建文档检索增强生成(RAG)系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性,但其核心优势在于为机器

93.4k|★★☆☆☆|1周前
插件开发框架