DeepAnalyze多GPU分布式训练指南如果你正在训练DeepAnalyze这类大型模型可能会遇到一个头疼的问题模型太大单张显卡根本装不下或者训练速度慢得像蜗牛爬。这时候多GPU分布式训练就成了你的救星。简单来说分布式训练就是让多张显卡一起干活共同分担计算任务。这不仅能让你训练更大的模型还能大幅缩短训练时间。想象一下原来需要一个月才能完成的训练现在可能几天就搞定了。今天这篇文章我就带你一步步搞定DeepAnalyze在多GPU环境下的分布式训练。我会用最直白的话把数据并行、梯度同步这些听起来高大上的概念讲清楚还会给你可以直接运行的代码。无论你是刚接触分布式训练的新手还是想优化现有训练流程的老手这篇文章都能给你实实在在的帮助。1. 准备工作环境与硬件检查在开始之前我们得先确保环境没问题。DeepAnalyze的分布式训练主要依赖PyTorch所以PyTorch的版本和CUDA环境是关键。1.1 硬件要求首先看看你的显卡。分布式训练对显卡有一定要求显卡数量至少2张相同型号的NVIDIA显卡。型号不同可能会导致性能问题。显存大小每张显卡的显存最好在16GB以上。DeepAnalyze-8B模型在训练时如果使用较大的批次大小单卡可能需要20GB的显存。显卡互联如果有多张显卡最好是通过NVLink连接这样数据传输速度更快。没有NVLink也能用只是效率会低一些。你可以用下面的命令检查显卡信息nvidia-smi这个命令会显示你所有显卡的型号、显存大小、使用情况等信息。确保所有显卡都能被系统识别。1.2 软件环境配置接下来是软件环境。我建议使用Python 3.10或3.11这两个版本和PyTorch的兼容性比较好。安装PyTorch# 根据你的CUDA版本选择对应的PyTorch安装命令 # CUDA 11.8 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # CUDA 12.1 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121验证安装import torch print(fPyTorch版本: {torch.__version__}) print(fCUDA是否可用: {torch.cuda.is_available()}) print(f可用显卡数量: {torch.cuda.device_count()}) print(f当前显卡: {torch.cuda.get_device_name(0)})如果一切正常你会看到类似这样的输出PyTorch版本: 2.3.0 CUDA是否可用: True 可用显卡数量: 2 当前显卡: NVIDIA GeForce RTX 40901.3 克隆DeepAnalyze代码如果你还没有DeepAnalyze的代码需要先克隆下来git clone https://github.com/ruc-datalab/DeepAnalyze.git cd DeepAnalyze然后安装必要的依赖pip install -r requirements.txt2. 理解分布式训练的核心概念在动手写代码之前我们先花几分钟搞清楚几个关键概念。别担心我用最生活化的例子来解释。2.1 数据并行像工厂流水线想象一下你有一个工厂要生产玩具。如果只有一条生产线单卡产量肯定有限。数据并行的思路就是复制多条相同的生产线多卡把原材料数据平均分给每条线大家同时生产。在深度学习中数据并行的工作流程是这样的模型复制把同一个模型复制到每张显卡上数据分割把训练数据分成若干份每张显卡处理一份独立计算每张显卡用自己的数据计算梯度模型需要调整的方向梯度同步把所有显卡计算的梯度汇总起来求个平均值统一更新用平均后的梯度更新所有显卡上的模型这样每张显卡都在处理不同的数据但模型始终保持一致。这是最常用、最简单的分布式训练方式。2.2 模型并行像拼图游戏当模型太大单张显卡装不下时就需要模型并行。这就像一张巨大的拼图一张桌子放不下我们把它分成几块每张桌子拼一部分。模型并行有两种常见方式层间并行把模型的不同层放到不同的显卡上。比如前几层在显卡A中间几层在显卡B最后几层在显卡C。张量并行把单个层的计算拆分成多个部分分别在不同显卡上计算。对于DeepAnalyze-8B这种规模的模型通常数据并行就够用了。但如果你的模型更大或者显卡显存很小可能需要考虑模型并行。2.3 梯度同步团队协作的关键梯度同步是数据并行的核心环节。每张显卡算完自己的梯度后需要把这些梯度汇总起来。PyTorch提供了几种同步方式All-Reduce所有显卡互相通信最终每张卡都有完整的平均梯度Ring-All-Reduce更高效的通信方式显卡组成一个环依次传递梯度在实际使用中我们通常不需要自己实现这些PyTorch的DistributedDataParallelDDP已经帮我们做好了优化。3. 单机多卡训练实战现在我们来实际配置一个单机多卡的训练环境。单机多卡是最常见的场景就是在一台服务器上使用多张显卡。3.1 基础分布式训练脚本我们先从一个最简单的例子开始。假设你已经有DeepAnalyze的训练脚本现在要把它改造成支持多GPU的版本。原来的单卡训练代码可能是这样的import torch from deepanalyze import DeepAnalyzeModel, get_dataloader def train_single_gpu(): # 初始化模型 model DeepAnalyzeModel.from_pretrained(RUC-DataLab/DeepAnalyze-8B) model.cuda() # 放到显卡上 # 准备数据 dataloader get_dataloader(batch_size8) # 优化器 optimizer torch.optim.AdamW(model.parameters(), lr1e-5) # 训练循环 for epoch in range(10): for batch in dataloader: inputs batch[input_ids].cuda() labels batch[labels].cuda() # 前向传播 outputs model(inputs, labelslabels) loss outputs.loss # 反向传播 loss.backward() optimizer.step() optimizer.zero_grad() print(fLoss: {loss.item():.4f})改造为多卡训练import torch import torch.distributed as dist import torch.multiprocessing as mp from torch.nn.parallel import DistributedDataParallel as DDP from torch.utils.data.distributed import DistributedSampler from deepanalyze import DeepAnalyzeModel, get_dataset def setup(rank, world_size): 初始化分布式环境 # 设置主节点地址和端口 os.environ[MASTER_ADDR] localhost os.environ[MASTER_PORT] 12355 # 初始化进程组 dist.init_process_group(nccl, rankrank, world_sizeworld_size) # 设置当前进程使用的显卡 torch.cuda.set_device(rank) def cleanup(): 清理分布式环境 dist.destroy_process_group() def train(rank, world_size): 每个GPU上运行的训练函数 # 设置分布式环境 setup(rank, world_size) # 初始化模型 model DeepAnalyzeModel.from_pretrained(RUC-DataLab/DeepAnalyze-8B) model model.to(rank) # 用DDP包装模型 model DDP(model, device_ids[rank]) # 准备数据 - 使用DistributedSampler dataset get_dataset() sampler DistributedSampler( dataset, num_replicasworld_size, rankrank, shuffleTrue ) dataloader torch.utils.data.DataLoader( dataset, batch_size4, # 这是每个GPU的批次大小 samplersampler, num_workers4, pin_memoryTrue ) # 优化器 optimizer torch.optim.AdamW(model.parameters(), lr1e-5) # 训练循环 for epoch in range(10): sampler.set_epoch(epoch) # 重要每个epoch重新shuffle数据 for batch_idx, batch in enumerate(dataloader): inputs batch[input_ids].to(rank, non_blockingTrue) labels batch[labels].to(rank, non_blockingTrue) # 前向传播 outputs model(inputs, labelslabels) loss outputs.loss # 反向传播 optimizer.zero_grad() loss.backward() optimizer.step() # 只在主进程打印日志 if rank 0 and batch_idx % 10 0: print(fEpoch {epoch}, Batch {batch_idx}, Loss: {loss.item():.4f}) # 保存模型只在主进程保存 if rank 0: torch.save(model.module.state_dict(), deepanalyze_finetuned.pth) # 清理 cleanup() def main(): 主函数启动多进程训练 world_size torch.cuda.device_count() print(f发现 {world_size} 张显卡开始分布式训练...) # 使用多进程启动训练 mp.spawn(train, args(world_size,), nprocsworld_size, joinTrue) if __name__ __main__: main()3.2 关键代码解释让我解释一下上面代码中的几个关键点setup()函数初始化分布式环境。MASTER_ADDR和MASTER_PORT指定了主节点的地址和端口。nccl是NVIDIA的通信库效率最高。DistributedDataParallelDDP这是PyTorch提供的分布式训练包装器。它会自动处理梯度同步你几乎不需要修改原来的模型代码。DistributedSampler确保每个GPU拿到不同的数据。它会自动把数据集分成若干份每份给一个GPU。sampler.set_epoch(epoch)这个很重要每个epoch都要调用确保数据在每个epoch都被重新打乱避免每个GPU总是看到相同顺序的数据。model.module当使用DDP包装后原来的模型变成了model.module。保存模型时要保存model.module.state_dict()。3.3 启动训练保存上面的代码为train_distributed.py然后直接运行python train_distributed.pyPyTorch会自动检测可用的GPU数量并为每个GPU启动一个进程。你会看到类似这样的输出发现 2 张显卡开始分布式训练... Epoch 0, Batch 0, Loss: 3.4567 Epoch 0, Batch 10, Loss: 2.8912 Epoch 0, Batch 20, Loss: 2.3456 ...4. 梯度同步优化技巧默认的DDP已经做了很多优化但在某些情况下我们还可以进一步优化。特别是当显卡数量很多或者模型很大的时候。4.1 梯度累积解决显存不足有时候即使使用了多卡每张卡的显存还是不够放下大的批次。这时候可以用梯度累积。梯度累积的原理是多次前向传播和反向传播但先不更新模型等累积了足够多的梯度后再一次性更新。# 在训练循环中加入梯度累积 accumulation_steps 4 # 累积4步再更新 optimizer.zero_grad() for batch_idx, batch in enumerate(dataloader): inputs batch[input_ids].to(rank) labels batch[labels].to(rank) # 前向传播 outputs model(inputs, labelslabels) loss outputs.loss # 反向传播但除以累积步数 loss loss / accumulation_steps loss.backward() # 每accumulation_steps步更新一次 if (batch_idx 1) % accumulation_steps 0: optimizer.step() optimizer.zero_grad() if rank 0: print(f更新参数当前Loss: {loss.item() * accumulation_steps:.4f})这样虽然实际批次大小是batch_size * accumulation_steps但显存占用只相当于batch_size。4.2 梯度裁剪防止梯度爆炸在分布式训练中梯度可能会变得很大导致训练不稳定。梯度裁剪可以限制梯度的大小。# 在optimizer.step()之前添加梯度裁剪 torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm1.0) optimizer.step()max_norm1.0表示所有梯度的L2范数不超过1.0。这个值可以根据实际情况调整。4.3 混合精度训练加快速度减少显存混合精度训练同时使用FP16半精度和FP32单精度可以显著减少显存使用并加快训练速度。from torch.cuda.amp import autocast, GradScaler # 初始化GradScaler scaler GradScaler() # 修改训练循环 for batch in dataloader: inputs batch[input_ids].to(rank) labels batch[labels].to(rank) optimizer.zero_grad() # 使用autocast进行混合精度训练 with autocast(): outputs model(inputs, labelslabels) loss outputs.loss # 使用scaler进行反向传播 scaler.scale(loss).backward() # 取消缩放梯度然后裁剪 scaler.unscale_(optimizer) torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm1.0) # 更新参数 scaler.step(optimizer) scaler.update()混合精度训练通常可以获得1.5-2倍的速度提升同时显存占用减少约一半。5. 多机多卡训练配置如果你的资源更充足或者模型特别大可能需要多台服务器一起训练。多机多卡的配置稍微复杂一些。5.1 环境配置假设你有两台服务器每台有4张显卡服务器A: 192.168.1.100 (显卡0-3)服务器B: 192.168.1.101 (显卡4-7)在每台服务器上# 修改setup函数 def setup(rank, local_rank, world_size, master_addr): os.environ[MASTER_ADDR] master_addr # 主服务器地址 os.environ[MASTER_PORT] 12355 # 全局rank和local rank global_rank rank local_rank local_rank dist.init_process_group( nccl, rankglobal_rank, world_sizeworld_size ) torch.cuda.set_device(local_rank)5.2 启动脚本你需要分别在两台服务器上启动训练脚本在服务器A上主节点# 启动4个进程对应4张显卡 python train_multi_node.py \ --world_size 8 \ --rank 0 \ --local_rank 0 \ --master_addr 192.168.1.100 \ --num_nodes 2 \ --node_rank 0在服务器B上# 同样启动4个进程 python train_multi_node.py \ --world_size 8 \ --rank 4 \ # 注意rank从4开始 --local_rank 0 \ --master_addr 192.168.1.100 \ # 指向主节点 --num_nodes 2 \ --node_rank 15.3 使用SLURM或Kubernetes在生产环境中通常使用作业调度系统如SLURM或者容器编排平台如Kubernetes来管理多机训练。SLURM示例#!/bin/bash #SBATCH --job-namedeepanalyze_train #SBATCH --nodes2 #SBATCH --ntasks-per-node4 #SBATCH --gresgpu:4 #SBATCH --time24:00:00 srun python train_multi_node.py \ --world_size 8 \ --master_addr $(hostname) \ --num_nodes 26. 常见问题与调试技巧分布式训练可能会遇到各种问题这里我总结了一些常见问题和解决方法。6.1 内存不足问题问题训练时出现CUDA out of memory错误。解决方法减小batch_size使用梯度累积使用混合精度训练使用梯度检查点checkpointing# 梯度检查点示例 from torch.utils.checkpoint import checkpoint class DeepAnalyzeWithCheckpoint(nn.Module): def forward(self, x): # 使用checkpoint节省显存 return checkpoint(self._forward, x) def _forward(self, x): # 原来的前向传播逻辑 return self.model(x)6.2 训练速度慢问题多卡训练速度没有明显提升。可能原因和解决方法数据加载瓶颈增加num_workers使用pin_memoryTrue通信开销大减少同步频率或使用更大的批次大小IO瓶颈使用更快的存储如NVMe SSD# 优化数据加载 dataloader DataLoader( dataset, batch_sizebatch_size, samplersampler, num_workers8, # 根据CPU核心数调整 pin_memoryTrue, prefetch_factor2 # 预取数据 )6.3 训练不稳定问题Loss波动大或者出现NaN。解决方法使用梯度裁剪调整学习率使用更稳定的优化器如AdamW添加梯度累积# 学习率预热 from torch.optim.lr_scheduler import LambdaLR def get_linear_schedule_with_warmup(optimizer, num_warmup_steps, num_training_steps): def lr_lambda(current_step): if current_step num_warmup_steps: return float(current_step) / float(max(1, num_warmup_steps)) return max(0.0, float(num_training_steps - current_step) / float(max(1, num_training_steps - num_warmup_steps))) return LambdaLR(optimizer, lr_lambda) # 使用 scheduler get_linear_schedule_with_warmup( optimizer, num_warmup_steps1000, num_training_steps100000 )6.4 调试技巧当分布式训练出现问题时可以按以下步骤调试先测试单卡确保单卡训练能正常工作减少规模测试用很小的数据集和模型测试多卡检查通信使用torch.distributed的调试工具# 检查所有进程是否正常同步 dist.barrier() # 所有进程会在这里等待直到所有进程都执行到这里 print(fRank {rank}: 通过同步点)7. 性能监控与优化训练过程中我们需要监控各种指标确保训练高效进行。7.1 监控GPU使用率# 实时监控GPU状态 watch -n 1 nvidia-smi # 更详细的监控 nvidia-smi --query-gputimestamp,name,utilization.gpu,utilization.memory,memory.total,memory.free,memory.used --formatcsv -l 17.2 使用PyTorch ProfilerPyTorch提供了性能分析工具可以帮助找到瓶颈from torch.profiler import profile, record_function, ProfilerActivity with profile( activities[ProfilerActivity.CPU, ProfilerActivity.CUDA], record_shapesTrue, profile_memoryTrue, with_stackTrue ) as prof: # 训练代码 for batch in dataloader: # ... 训练步骤 ... pass # 输出分析结果 print(prof.key_averages().table(sort_bycuda_time_total, row_limit10))7.3 日志记录在分布式训练中合理的日志记录很重要import logging from datetime import datetime def setup_logging(rank): if rank 0: # 只在主进程记录日志 logging.basicConfig( levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(ftrain_{datetime.now().strftime(%Y%m%d_%H%M%S)}.log), logging.StreamHandler() ] ) else: logging.basicConfig(levellogging.WARNING) # 其他进程只记录错误 # 在训练中使用 if rank 0 and batch_idx % 100 0: logging.info(fEpoch {epoch}, Loss: {loss.item():.4f}, LR: {scheduler.get_last_lr()[0]:.6f})8. 实际训练示例微调DeepAnalyze让我们看一个完整的示例展示如何用多GPU微调DeepAnalyze模型。#!/usr/bin/env python3 DeepAnalyze多GPU微调脚本 支持数据并行、混合精度训练、梯度累积 import os import torch import torch.distributed as dist import torch.multiprocessing as mp from torch.nn.parallel import DistributedDataParallel as DDP from torch.utils.data.distributed import DistributedSampler from torch.cuda.amp import autocast, GradScaler from transformers import AutoTokenizer, default_data_collator from deepanalyze import DeepAnalyzeModel, DataScienceDataset import logging from datetime import datetime def setup_distributed(rank, world_size): 设置分布式训练环境 os.environ[MASTER_ADDR] localhost os.environ[MASTER_PORT] 12355 dist.init_process_group(nccl, rankrank, world_sizeworld_size) torch.cuda.set_device(rank) return rank, world_size def cleanup_distributed(): 清理分布式环境 dist.destroy_process_group() def train_deepanalyze(rank, world_size, args): 训练函数 # 设置分布式 rank, world_size setup_distributed(rank, world_size) # 设置日志只在主进程 if rank 0: timestamp datetime.now().strftime(%Y%m%d_%H%M%S) logging.basicConfig( levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(fdeepanalyze_train_{timestamp}.log), logging.StreamHandler() ] ) logger logging.getLogger(__name__) logger.info(f开始训练使用 {world_size} 张GPU) # 加载模型和分词器 if rank 0: logger.info(加载模型和分词器...) model DeepAnalyzeModel.from_pretrained( args.model_path, torch_dtypetorch.float16 if args.fp16 else torch.float32 ) model model.to(rank) tokenizer AutoTokenizer.from_pretrained(args.model_path) # 使用DDP包装模型 model DDP(model, device_ids[rank], find_unused_parametersFalse) # 准备数据集 if rank 0: logger.info(准备数据集...) dataset DataScienceDataset( data_pathargs.data_path, tokenizertokenizer, max_lengthargs.max_length ) sampler DistributedSampler( dataset, num_replicasworld_size, rankrank, shuffleTrue ) dataloader torch.utils.data.DataLoader( dataset, batch_sizeargs.batch_size, samplersampler, num_workersargs.num_workers, pin_memoryTrue, collate_fndefault_data_collator, prefetch_factor2 ) # 优化器和学习率调度器 optimizer torch.optim.AdamW( model.parameters(), lrargs.learning_rate, weight_decayargs.weight_decay ) total_steps len(dataloader) * args.num_epochs warmup_steps int(total_steps * 0.1) # 10%的步数用于预热 from torch.optim.lr_scheduler import LambdaLR scheduler LambdaLR( optimizer, lr_lambdalambda step: min(1.0, step / warmup_steps) if step warmup_steps else 1.0 ) # 混合精度训练 scaler GradScaler(enabledargs.fp16) # 训练循环 if rank 0: logger.info(开始训练循环...) global_step 0 for epoch in range(args.num_epochs): sampler.set_epoch(epoch) if rank 0: logger.info(f开始第 {epoch 1}/{args.num_epochs} 轮训练) model.train() for batch_idx, batch in enumerate(dataloader): # 将数据移到GPU inputs {k: v.to(rank, non_blockingTrue) for k, v in batch.items()} optimizer.zero_grad() # 混合精度训练 with autocast(enabledargs.fp16): outputs model(**inputs) loss outputs.loss # 梯度累积 loss loss / args.gradient_accumulation_steps scaler.scale(loss).backward() # 每accumulation_steps步更新一次 if (batch_idx 1) % args.gradient_accumulation_steps 0: # 梯度裁剪 scaler.unscale_(optimizer) torch.nn.utils.clip_grad_norm_( model.parameters(), max_normargs.max_grad_norm ) # 更新参数 scaler.step(optimizer) scaler.update() scheduler.step() optimizer.zero_grad() global_step 1 # 记录日志 if rank 0 and global_step % args.logging_steps 0: current_lr scheduler.get_last_lr()[0] logger.info( fStep {global_step}, fLoss: {loss.item() * args.gradient_accumulation_steps:.4f}, fLR: {current_lr:.2e} ) # 保存检查点 if rank 0 and global_step % args.save_steps 0: checkpoint_path f{args.output_dir}/checkpoint-{global_step} os.makedirs(checkpoint_path, exist_okTrue) # 保存模型 model.module.save_pretrained(checkpoint_path) tokenizer.save_pretrained(checkpoint_path) logger.info(f保存检查点到 {checkpoint_path}) # 最终保存 if rank 0: final_path f{args.output_dir}/final_model model.module.save_pretrained(final_path) tokenizer.save_pretrained(final_path) logger.info(f训练完成模型保存到 {final_path}) # 清理 cleanup_distributed() def main(): import argparse parser argparse.ArgumentParser(descriptionDeepAnalyze多GPU训练) parser.add_argument(--model_path, typestr, requiredTrue, help模型路径) parser.add_argument(--data_path, typestr, requiredTrue, help数据路径) parser.add_argument(--output_dir, typestr, default./output, help输出目录) parser.add_argument(--num_epochs, typeint, default3, help训练轮数) parser.add_argument(--batch_size, typeint, default4, help每个GPU的批次大小) parser.add_argument(--learning_rate, typefloat, default2e-5, help学习率) parser.add_argument(--max_length, typeint, default2048, help最大序列长度) parser.add_argument(--gradient_accumulation_steps, typeint, default4, help梯度累积步数) parser.add_argument(--max_grad_norm, typefloat, default1.0, help梯度裁剪阈值) parser.add_argument(--weight_decay, typefloat, default0.01, help权重衰减) parser.add_argument(--logging_steps, typeint, default100, help日志记录步数) parser.add_argument(--save_steps, typeint, default1000, help保存检查点步数) parser.add_argument(--num_workers, typeint, default4, help数据加载工作进程数) parser.add_argument(--fp16, actionstore_true, help使用混合精度训练) args parser.parse_args() # 创建输出目录 os.makedirs(args.output_dir, exist_okTrue) # 获取GPU数量 world_size torch.cuda.device_count() print(f检测到 {world_size} 张GPU) # 启动分布式训练 mp.spawn( train_deepanalyze, args(world_size, args), nprocsworld_size, joinTrue ) if __name__ __main__: main()使用这个脚本进行训练# 单机多卡训练 python train_deepanalyze_distributed.py \ --model_path RUC-DataLab/DeepAnalyze-8B \ --data_path ./your_data \ --output_dir ./deepanalyze_finetuned \ --num_epochs 3 \ --batch_size 2 \ --gradient_accumulation_steps 8 \ --fp16这个脚本包含了我们讨论的所有优化技巧数据并行、混合精度训练、梯度累积、梯度裁剪、学习率预热等。9. 总结与建议经过上面的介绍你应该对DeepAnalyze的多GPU分布式训练有了全面的了解。在实际使用中我有几个建议首先分布式训练确实能大幅提升训练效率但也不是显卡越多越好。随着显卡数量增加通信开销也会增大。通常4-8张显卡的性价比最高超过16张后提升可能就不明显了。其次调试分布式训练要有耐心。遇到问题时先从最简单的配置开始逐步增加复杂度。先确保单卡能跑通再测试两卡最后扩展到多卡。另外监控和日志很重要。训练过程中要密切关注GPU使用率、显存占用、Loss曲线等指标。这些信息能帮你及时发现问题和优化配置。最后根据你的具体需求选择合适的策略。如果只是微调模型数据并行通常就足够了。如果要训练特别大的模型可能需要结合模型并行。DeepAnalyze-8B这个规模用数据并行加混合精度训练在4张24GB显存的显卡上就能很好地训练。实际用下来DeepAnalyze的分布式训练配置起来并不复杂PyTorch的DDP已经做了很多封装。关键是要理解背后的原理这样遇到问题时才知道怎么调整。希望这篇文章能帮你顺利开始分布式训练如果有具体问题可以多看看官方文档和社区讨论。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。