动手实践看懂深度学习的DP和DDP

31 篇文章 8 订阅
订阅专栏

摘要

为了尽可能加快训练,我们会使用两种GPU并行手段,DP和DDP,但是DP其实只会开一个进程去管理,计算资源分配不均,DDP上我们倾向于一张卡开一个进程,使得我们的计算资源能够最大化的利用。本次的文章会快速地形象地过一下DP和DDP并且告诉大家如何代码层面上实践。

DP

在这里插入图片描述
从图中我们可以看出,在forward环节,gpu1会先把所有的数据拿到,然后分发给其他的gpu,当然它自己也拿一份,接着它把自己的模型也复制成4份,每个gpu也拿一份,每个gpu自己跑自己的forward,跑完后将output传给gpu1,gpu1处理所有的output对应的梯度,然后进行backward,将要反向传播的梯度分配给其他的gpu,然后其他的gpu又各自进行自己的反向计算,计算完后将最后的梯度交给gpu1进行更新。我们可以看到,在gpu1分配任务和更新的时候,其实其他的gpu其实都是闲置的,所以利用率没法上来,全部人都得等gpu1。那么我们可不可以想一种新方法来让每个gpu自己拿到数据后,自己跑前后向,而且自己更新梯度呢?DDP这不就来了嘛!

DDP

在这里插入图片描述
秉着尽量少理论,多形象的原则,加速理解,看图。我们将我们的数据以一个一个的batch传入网络,我们有两台machine,两台machine上各有两台gpu。每台gpu上都有自己的model(都是同一个model的复制品)和optimizer。每次来一个batch的数据,我们都会让Distributed sampler去将数据分配好发给指定的gpu,然后gpu们自己跑自己的,跑完前向后,每个gpu通过DDP的后端通讯可以知道其他所有gpu跑的结果,同步了所有gpu的梯度,拿到所有的信息后就吭哧吭哧自己去反向传播更新梯度。DDP就这么简单。

DDP代码实践

在这里插入图片描述

# 1. 导包:一些需要导入的库
# 模型相关
from torch.nn.parallel import DistributedDataParallel as DDP
# 数据相关
from torch.utils.data.distributed import DistributedSampler
# ddp自身的机制相关
import torch.distributed as dist

# 2.后端多卡通讯及GPU序号(RANK)
if DDP_ON:
    init_process_group(backend="nccl")
    LOCAL_RANK = device_id = int(os.environ["LOCAL_RANK"])
    WORLD_SIZE = torch.cuda.device_count()

    device = torch.device('cuda', device_id) # note that device_id is an integer but device is a datetype.
    print(f"Start running basic DDP on rank {LOCAL_RANK}.")
    logging.info(f'Using device {device_id}')

# 3. DDP model
net = DDP(net, device_ids = [device_id], output_device=device_id)


# 4.喂数据给多卡
loader_args = dict(batch_size=batch_size, num_workers=WORLD_SIZE*4, pin_memory=True) # batchsize is for a single proc
if DDP_ON:
    train_sampler = DistributedSampler(train_set)
    train_loader = DataLoader(train_set, sampler=train_sampler, **loader_args)
else:
    train_loader = DataLoader(train_set, shuffle=True, **loader_args)
    
# no need for distributed sampler for val
val_loader = DataLoader(val_set, shuffle=False, drop_last=True, **loader_args)


# 5.set_epoch 防止每次数据都是一样的(如下图)
# ref: https://blog.csdn.net/weixin_41978699/article/details/121742647
for epoch in range(start, start+epochs):
    if LOCAL_RANK == 0:
        print('lr: ', optimizer.param_groups[0]['lr']) 

    net.train()
    epoch_loss = 0

    # To avoid duplicated data sent to multi-gpu
    train_loader.sampler.set_epoch(epoch)

在这里插入图片描述

启动

torchrun --nproc_per_node=4 \
          multigpu_torchrun.py \
          --batch_size 4 \
          --lr 1e-3
python -m torch.distributed.launch \
      --nproc_per_node = 4 \
        train.py \
      --batch_size 4

完整代码布局参考

import argparse
import logging
import sys
from pathlib import Path

import torch
import torch.nn as nn
import torch.nn.functional as F
import wandb
from torch import optim
from torch.utils.data import DataLoader, random_split
from tqdm import tqdm

from utils.data_loading import BasicDataset, CarvanaDataset
from utils.dice_score import dice_loss
from evaluate import evaluate
from unet import UNet
import os
import torch.distributed as dist

# for reproducibility
import random
import numpy as np
import torch.backends.cudnn as cudnn

# ABOUT DDP
# for model loading in ddp mode
from torch.nn.parallel import DistributedDataParallel as DDP
# for data loading in ddp mode
from torch.utils.data.distributed import DistributedSampler

import torch.multiprocessing as mp
from torch.distributed import init_process_group, destroy_process_group



def init_seeds(seed=0, cuda_deterministic=True):
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    # Speed-reproducibility tradeoff https://pytorch.org/docs/stable/notes/randomness.html
    if cuda_deterministic:  # slower, more reproducible
        cudnn.deterministic = True
        cudnn.benchmark = False
    else:  # faster, less reproducible
        cudnn.deterministic = False
        cudnn.benchmark = True

def train_net(net,
              device,
              start: int = 0,
              epochs: int = 5,
              batch_size: int = 1,
              learning_rate: float = 1e-5,
              val_percent: float = 0.1,
              save_checkpoint: bool = True,
              img_scale: float = 0.5,
              amp: bool = False):
    

    if DDP_ON: # modify the net's attributes when using ddp
        net.n_channels = net.module.n_channels
        net.n_classes  = net.module.n_classes

    # 1. Create dataset
    try:
        dataset = CarvanaDataset(dir_img, dir_mask, img_scale)
    except (AssertionError, RuntimeError):
        dataset = BasicDataset(dir_img, dir_mask, img_scale)

    # 2. Split into train / validation partitions
    n_val = int(len(dataset) * val_percent)
    n_train = len(dataset) - n_val
    train_set, val_set = random_split(dataset, [n_train, n_val], generator=torch.Generator().manual_seed(0))

    # 3. Create data loaders
    loader_args = dict(batch_size=batch_size, num_workers=WORLD_SIZE*4, pin_memory=True) # batchsize is for a single process(GPU)

    if DDP_ON:
        train_sampler = DistributedSampler(train_set)
        train_loader = DataLoader(train_set, sampler=train_sampler, **loader_args)
    else:
        train_loader = DataLoader(train_set, shuffle=True, **loader_args)
    
    
    # no need for distributed sampler for val
    val_loader = DataLoader(val_set, shuffle=False, drop_last=True, **loader_args)
    
    # (Initialize logging)
    if LOCAL_RANK == 0:
        experiment = wandb.init(project='U-Net-DDP', resume='allow', anonymous='must')
        experiment.config.update(dict(epochs=epochs, batch_size=batch_size, learning_rate=learning_rate,
                                  val_percent=val_percent, save_checkpoint=save_checkpoint, img_scale=img_scale,
                                  amp=amp))
            
        logging.info(f'''Starting training:
                Epochs:          {epochs}
                Start from:      {start}
                Batch size:      {batch_size}
                Learning rate:   {learning_rate}
                Training size:   {n_train}
                Validation size: {n_val}
                Checkpoints:     {save_checkpoint}
                Device:          {device.type}
                Images scaling:  {img_scale}
                Mixed Precision: {amp}
            ''')

    # 4. Set up the optimizer, the loss, the learning rate scheduler and the loss scaling for AMP
    criterion = nn.CrossEntropyLoss() 
    
    optimizer = optim.AdamW(net.parameters(), lr=learning_rate, weight_decay=1e-8)
    scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=epochs, eta_min=1e-7)
    grad_scaler = torch.cuda.amp.GradScaler(enabled=amp)
    global_step = 0

    # 5. Begin training
    for epoch in range(start, start+epochs):
        if LOCAL_RANK == 0:
            print('lr: ', optimizer.param_groups[0]['lr']) 
        
        net.train()
        epoch_loss = 0

        # To avoid duplicated data sent to multi-gpu
        train_loader.sampler.set_epoch(epoch)

        disable = False if LOCAL_RANK == 0 else True

        with tqdm(total=n_train, desc=f'Epoch {epoch}/{epochs+start}', unit='img', disable=disable) as pbar:
            for batch in train_loader:
                images = batch['image']
                true_masks = batch['mask']
                    
                assert images.shape[1] == net.n_channels, \
                    f'Network has been defined with {net.n_channels} input channels, ' \
                    f'but loaded images have {images.shape[1]} channels. Please check that ' \
                    'the images are loaded correctly.'

                images = images.to(device=device, dtype=torch.float32)
                true_masks = true_masks.to(device=device, dtype=torch.long)

                with torch.cuda.amp.autocast(enabled=amp):
                    masks_pred = net(images)
                    loss = criterion(masks_pred, true_masks) \
                           + dice_loss(F.softmax(masks_pred, dim=1).float(),
                                       F.one_hot(true_masks, net.n_classes).permute(0, 3, 1, 2).float(),
                                       multiclass=True)

                optimizer.zero_grad(set_to_none=True)
                grad_scaler.scale(loss).backward()
                grad_scaler.step(optimizer)
                grad_scaler.update()

                pbar.update(images.shape[0])
                global_step += 1
                epoch_loss += loss.item()

                if LOCAL_RANK == 0:
                    experiment.log({
                        'train loss': loss.item(),
                        'step': global_step,
                        'epoch': epoch
                    })
                pbar.set_postfix(**{'loss (batch)': loss.item()})

                # Evaluation round
                division_step = (n_train // (5 * batch_size))
                if division_step > 0:
                    if global_step % division_step == 0:
                        histograms = {}
                        for tag, value in net.named_parameters():
                            tag = tag.replace('/', '.')
                            if not torch.isinf(value).any():
                                histograms['Weights/' + tag] = wandb.Histogram(value.data.cpu())
                            if not torch.isinf(value.grad).any():
                                histograms['Gradients/' + tag] = wandb.Histogram(value.grad.data.cpu())

                        val_score = evaluate(net, val_loader, device, disable_log = disable)

                        if LOCAL_RANK == 0:
                            logging.info('Validation Dice score: {}'.format(val_score))
                            experiment.log({
                                'learning rate': optimizer.param_groups[0]['lr'],
                                'validation Dice': val_score,
                                'images': wandb.Image(images[0].cpu()),
                                'masks': {
                                    'true': wandb.Image(true_masks[0].float().cpu()),
                                    'pred': wandb.Image(masks_pred.argmax(dim=1)[0].float().cpu()),
                                },
                                'step': global_step,
                                'epoch': epoch,
                                **histograms
                            })
        scheduler.step()
        if save_checkpoint and LOCAL_RANK == 0 and (epoch % args.save_every == 0):
            Path(dir_checkpoint).mkdir(parents=True, exist_ok=True)
            torch.save(net.module.state_dict(), str(dir_checkpoint / 'DDP_checkpoint_epoch{}.pth'.format(epoch)))
            
            logging.info(f'Checkpoint {epoch} saved!')


##################################### arguments ###########################################
parser = argparse.ArgumentParser(description='Train the UNet on images and target masks')
parser.add_argument('--epochs', '-e', metavar='E', type=int, default=5, help='Number of epochs')
parser.add_argument('--batch-size', '-b', dest='batch_size', metavar='B', type=int, default=1, help='Batch size')
parser.add_argument('--learning-rate', '-l', metavar='LR', type=float, default=1e-5,
                    help='Learning rate', dest='lr')
parser.add_argument('--load', '-f', type=str, default=False, help='Load model from a .pth file')
parser.add_argument('--scale', '-s', type=float, default=0.5, help='Downscaling factor of the images')
parser.add_argument('--validation', '-v', dest='val', type=float, default=10.0,
                    help='Percent of the data that is used as validation (0-100)')
parser.add_argument('--amp', action='store_true', default=False, help='Use mixed precision')
parser.add_argument('--bilinear', action='store_true', default=False, help='Use bilinear upsampling')
parser.add_argument('--classes', '-c', type=int, default=2, help='Number of classes')
parser.add_argument('--exp_name', type=str, default='hgb_exp')
parser.add_argument('--ddp_mode', action='store_true')
parser.add_argument('--save_every', type=int, default=5)
parser.add_argument('--start_from', type=int, default=0)




args = parser.parse_args()

dir_img = Path('./data/imgs/')
dir_mask = Path('./data/masks/')
dir_checkpoint = Path('./checkpoints/')

DDP_ON = True if args.ddp_mode else False

#########################################################################################

if DDP_ON:
    init_process_group(backend="nccl")
    LOCAL_RANK = device_id = int(os.environ["LOCAL_RANK"])
    WORLD_SIZE = torch.cuda.device_count()

    device = torch.device('cuda', device_id) # note that device_id is an integer but device is a datetype.
    print(f"Start running basic DDP on rank {LOCAL_RANK}.")
    logging.info(f'Using device {device_id}')


if __name__ == '__main__':
    #!highly recommended]
    # ref: pytorch org ddp tutorial 
    # 1. https://pytorch.org/tutorials/beginner/ddp_series_multigpu.html#multi-gpu-training-with-ddp
    # 2. https://pytorch.org/tutorials/beginner/ddp_series_multigpu.html
    
    init_seeds(0)
    # Change here to adapt to your data
    # n_channels=3 for RGB images
    # n_classes is the number of probabilities you want to get per pixel
    net = UNet(n_channels=3, n_classes=args.classes, bilinear=args.bilinear)
    
    if LOCAL_RANK == 0:
        print(f'Network:\n'
            f'\t{net.n_channels} input channels\n'
            f'\t{net.n_classes} output channels (classes)\n'
            f'\t{"Bilinear" if net.bilinear else "Transposed conv"} upscaling')

    if args.load:
        # ref: https://blog.csdn.net/hustwayne/article/details/120324639  use method 2 with module
        # net.load_state_dict(torch.load(args.load, map_location=device))
        net.load_state_dict({k.replace('module.', ''): v for k, v in                 
                       torch.load(args.load, map_location=device).items()})

        logging.info(f'Model loaded from {args.load}')


    torch.cuda.set_device(LOCAL_RANK)
    net.to(device=device)
    # wrap our model with ddp
    net = DDP(net, device_ids = [device_id], output_device=device_id)

    try:
        train_net(net=net,
                  start=args.start_from,
                  epochs=args.epochs,
                  batch_size=args.batch_size,
                  learning_rate=args.lr,
                  device=device,
                  img_scale=args.scale,
                  val_percent=args.val / 100,
                  amp=args.amp)
    except KeyboardInterrupt:
        torch.save(net.module.state_dict(), 'INTERRUPTED_DDP.pth')
        logging.info('Saved interrupt')
        raise
    destroy_process_group()
LLM系列(3):探索大模型RLHF优化之道:DeepSpeed-Chat超快速入门,对齐训练精度提升一步到位
丨汀、的博客
05-01 267
LLM系列(3):探索大模型RLHF优化之道:DeepSpeed-Chat超快速入门,对齐训练精度提升一步到位
Pytorch 并行训练(DPDDP)的原理和应用
热门推荐
生命在于折腾!
09-27 1万+
Pytorch 并行训练(DPDDP)的原理和应用 1. 前言 并行训练可以分为数据并行和模型并行。 模型并行 模型并行主要应用于模型相比显存来说更大,一块 device 无法加载的场景,通过把模型切割为几个部分,分别加载到不同的 device 上。比如早期的 AlexNet,当时限于显卡,模型就是分别加载在两块显卡上的。 数据并行 这个是日常会应用的比较多的情况。每一个 device 上会加载一份模型,然后把数据分发到每个 device 并行进行计算,加快训练速度。 如果要再细分,又可以分
【原创 深度学习与TensorFlow 动手实践系列 - 4】第四课:卷积神经网络 - 高级篇...
weixin_34185560的博客
01-08 223
【原创 深度学习与TensorFlow 动手实践系列 - 4】第四课:卷积神经网络 - 高级篇           提纲: 1. AlexNet:现代神经网络起源 2. VGG:AlexNet增强版 3. GoogleNet:多维度识别 4. ResNet:机器超越人类识别 5. DeepFace:结构化图片的特殊处理 6. U-Net:图片生成网络 7. 实例:...
大模型分布式训练技术(DPDDP和FSDP
最新发布
yangtuoi的博客
08-26 921
本文主要讲解了大模型分布式训练并行技术的数据并行,并以Pytorch为主线讲解了DPDDP、FSDP三种不同的数据并行方案。单进程多线程模式,由于锁的机制导致线程间同步存在瓶颈。使用普通的All-Reduce机制,所有的卡需要将梯度同步给0号节点,并由0号节点平均梯度后反向传播,再分发给所有其他节点,意味着0号节点负载很重。由于第二点的原因,导致0号GPU通讯成本是随着GPU数量的上升而线性上升的。不支持多机多卡。目前,由于性能问题,DP基本不用了。
分布式训练(中)——DPDDP模式
xiaoyuer的博客
05-29 3159
1、在DP中,每个GPU上都拷贝一份完整的模型,每个GPU上处理batch的一部分数据,所有GPU算出来的梯度进行累加后,再传回各GPU用于更新参数2、DP多采用参数服务器这一编程框架,一般由若个计算Worker和1个梯度聚合Server组成。Server与每个Worker通讯,Worker间并不通讯。因此Server承担了系统所有的通讯压力。基于此DP常用于单机多卡场景。
分布式并行训练(DPDDP、DeepSpeed、Accelerate、Trainer)
ZhengrongYue的博客
09-27 5400
分布式并行训练(DPDDP、DeepSpeed)
ACM学习:DP深度学习
qq_62906846的博客
06-19 526
本周因为备考,学习时间主要挤在周末,所以题大多是囫囵吞枣式看的,看了大概20多道,这些DP题大多都比较复杂,需要理清自己的做题思路,并详细的思考前后关系,再得出状态转移方程。这也表示了普遍dp问题的一个重要的点:思路是关乎题目难度的重要标尺。......
分布式训练 - 单机多卡(DPDDP
love1005lin的博客
05-04 1万+
起初为调用大规模的模型训练,单卡GPU是不够使用的,需要借用服务器的多GPU使用。就会涉及到单机多卡,多机多卡的使用。在这里记录一下使用的方式和踩过的一些坑。文中若有不足,请多多指正。 由于分布式的内容较多,笔者准备分几篇来讲一次下深度学习的分布式训练,深度学习的框架使用的是Pytorch框架。 ----1.分布式训练的理论基础 ----2.GPU训练 ----3.单机多卡的使用 ----4.多机多卡的使用 在GPU训练文章中我们已经了解到了多GPU的训练,最简单的是单机多卡操作torch.nn.DataP
分布式训练 - 多机多卡 (DDP)
love1005lin的博客
05-06 1万+
起初为调用大规模的模型训练,单卡GPU是不够使用的,需要借用服务器的多GPU使用。就会涉及到单机多卡,多机多卡的使用。在这里记录一下使用的方式和踩过的一些坑。文中若有不足,请多多指正。 由于分布式的内容较多,笔者准备分几篇来讲一次下深度学习的分布式训练,深度学习的框架使用的是Pytorch框架。 ----1.分布式训练的理论基础 ----2.GPU训练 ----3.单机多卡的使用 ----4.多机多卡的使用 在前边的文章中已经提到了怎样进行单机单卡和单机多卡进行分布式训练,那可能有小伙伴会有疑问能不能进行多
[原创][深度][PyTorch] DDP入门教程
YIforeveralone的博客
10-26 2919
引言 本文首发于 知乎 DistributedDataParallel(DDP)是一个支持多机多卡训练、分布式训练的工程方法。PyTorch现已原生支持DDP,可以直接通过torch.distributed使用,超方便,不再需要难以安装的apex库啦! 概览 想要让你的PyTorch神经网络在多卡环境上跑得又快又好?那你definitely需要这一篇! No one knows DDP better than I do! – – magic_frog(手动狗头) 本文是DDP系列三篇(基本原理与入门
windbg调试和断点学习总结2
bcbobo21cn的专栏
12-13 1万+
WinDbg 设置断点 在windbg中,断点设置的地址形式有好多种,可以是以下几种: 1.虚拟地址:即给出直接地址,如 12345678 2.函数偏移量:如DriverEntry+5c. 3.源代码+行数 :`[[Module!]Filename][:LineNumber]` 4.对C++可以对模块中的某个类的方法设置断点:   设置断点语法:           1:
简版:读、实践动手深度学习
weixin_44298961的博客
04-28 1821
主要是记录一下我自己的学习历程,简单、快速为主。
大模型训练~数据并行
whaosoft143ai的博客
05-28 1433
1、在DP中,每个GPU上都拷贝一份完整的模型,每个GPU上处理batch的一部分数据,所有GPU算出来的梯度进行累加后,再传回各GPU用于更新参数2、DP多采用参数服务器这一编程框架,一般由若个计算Worker和1个梯度聚合Server组成。Server与每个Worker通讯,Worker间并不通讯。因此Server承担了系统所有的通讯压力。基于此DP常用于单机多卡场景。3、异步梯度更新是提升计算通讯比的一种方法,延迟更新的步数大小决定了模型的收敛速度。 whaosoft aiot http://143a
深度学习实战(27)】「分布式训练」DDP单机多卡并行指南
m0_51579041的博客
04-30 1496
深度学习实战(27)】「分布式训练」DDP单机多卡并行指南
Pytorch 分布式训练 (DP, DDP)
连理o的博客
10-30 7514
pytorch: DP and DDP
『PyTorch学习笔记』分布式深度学习训练中的数据并行(DP/DDP) VS 模型并行
AI新视界
11-30 1181
现代深度学习模型中的参数数量越来越大,数据集的规模也急剧增加。要在大型数据集上训练复杂的现代深度学习模型,必须使用多节点训练,否则会花费很长时间。在分布式深度学习训练中,人们可能总会看到数据并行和模型并行。在这篇博文中,将讨论这两种深度学习并行方法的理论、逻辑和一些误导点。
深度学习框架】pytorch之分布式数据并行化DDP
tobefans的博客
06-23 1998
DistributedDataParallel(DDP)是一个支持多机多卡、分布式训练的深度学习工程方法。它将数据并行划分到多个进程,各进程初始化模型并由各自的数据训练,再通过Ring-Reduce进行梯度交换与合并,实现进程数倍数的效率。 ..................
深度学习分布式训练DPDDP通信原理
欢迎光临啊噗不是阿婆主的酒馆
04-23 2408
日常在「九点澡堂子」裸泳,欢迎关注 ~ 前言 上周末开始写这篇文章,一度以为自己快要写完了。 写着写着发现参考资料有点争议,下文讲到的PS架构的实现在网络上说法不一。 鉴于是一个快要被淘汰的方案, Parrots里直接省略了该实现,所以堂妹对它背后的实现确实不太清楚。 本着传播知识的良知,不敢造次,查了很多资料,发现众说纷纭。 涉及上层模型的搭建场景,众所周知(假装),堂妹接触底层多一些, 于是乎,堂妹拉着贵司的研究员们一起探讨这个问题,毕竟他们模型搭的多。 凌晨2点,大佬依然在线… 大概是现代人的标配吧
深度学习框架分布式训练教程与实践
资源摘要信息:"各种深度学习(DL)框架分布式训练.zip"是一个包含了多个深度学习框架分布式训练教程和相关资源的压缩文件包。该文件集合了当前流行的几种深度学习框架的分布式训练方法,涵盖了Tensorflow、...
写文章

热门文章

  • 机器学习之线性回归(Linear Regression)算法 19199
  • 将cmd中命令输出保存为txt文本文件 17132
  • 即学即用的30个python常用代码 14843
  • YOLOv8模型网络结构图 14380
  • 制作你自己的yolov5数据集并进行训练 13233

分类专栏

  • YOLOV5 付费 21篇
  • LLMs 21篇
  • NLP 7篇
  • 模型部署 1篇
  • BestYOLO 10篇
  • 图像配准 6篇
  • Python 26篇
  • 不可不知 36篇
  • 深度学习 13篇
  • 问题解决 1篇
  • 偏爱小技巧 40篇
  • 竞赛之神 30篇
  • Linux 14篇
  • AI不可错过的知识点 31篇
  • 源码 15篇
  • 数据结构Code 7篇
  • C/C++ 2篇
  • 飞桨 6篇
  • AI开发的从0到1 9篇
  • 机器学习 25篇
  • GIt 11篇
  • Windows 11篇

最新评论

  • HTML实现随机点名

    2401_84215021: 代码运行有问题

  • Huggingface上传自己的预训练模型(大小权重都可以)

    晓零清: 这个需要代理吗?

  • Meta的LLama模型非官方下载方法

    落难Coder: 请使用ModelScope或者HF-mirror进行加速下载

  • Meta的LLama模型非官方下载方法

    dry86: 这种方式是不是下载不了 7b-Instruct这种微调的模型了

  • Albumentations数据增强部分方法使用和可视化展示

    aquanvip: HorizontalFlip 水平翻转

最新文章

  • LLM 推理的核心评估指标
  • 使用 HyDE 改善 RAG 回复的精确度
  • RAG 中进行 Rewrite 的prompt
2024年29篇
2023年25篇
2022年248篇
2021年2篇
2020年17篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落难Coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家铜仁六盘水玻璃钢雕塑报价蜘蛛侠玻璃钢雕塑江门能透光玻璃钢雕塑摆件玻璃钢花箱里面可以放花盆吗玻璃钢彩椒雕塑招牌标识标志柳州玻璃钢商场美陈杭州玻璃钢花盆设计企业深圳定制玻璃钢雕塑江苏开业商场美陈供货商开封不锈钢仿古玻璃钢仿铜雕塑驻马店专业玻璃钢人物雕塑玻璃钢镀晶雕塑天马行空淮南玻璃钢雕塑上海玻璃钢人物雕塑制作厂家苏州玻璃钢仿真雪糕雕塑江苏户外玻璃钢雕塑设计性价比高的景观玻璃钢雕塑上海玻璃钢雕塑销售电话唐山人物玻璃钢雕塑安装艺术商场美陈供应泰州玻璃钢人物雕塑商家湖南玻璃钢动物雕塑品牌信阳抽象玻璃钢仿铜雕塑厂家商场立面美陈玻璃钢雕塑厂家皆选艾牧景观雕塑滁州景区玻璃钢雕塑定制玻璃钢雕塑测试西藏玻璃钢解放军现代人雕塑厂家虹口商场美陈浙江步行街玻璃钢雕塑批发香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化