首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

HW4-补充4:模型参数与显存的关系,以及不同精度的影响

  • 25-02-16 23:21
  • 4440
  • 12035
blog.csdn.net

目录

0 前言

1 模型参数与显存的关系

1.1 理论计算

1.2 GPU显存需求

训练时的显存占用

推理时的显存占用

通过VRAM Estimator进行展示

2 不同精度的导入方式及其影响

2.1 常见的数值精度格式

2.2 对精度占用的影响

2.3 精度的权衡与选择

准确性 vs 性能

何时选择何种精度

2.4 硬件兼容性

3 实际应用

3.1 使用FP16精度

3.2 使用BF16精度

3.3 使用INT8量化

3.4 实践示例

对比不同精度下的显存占用

4 常见问题及解决方案

4.1 问题一:RuntimeError解决方法

4.2 问题二:TypeError解决方法

5 总结

6 完整例子(解释模型在加载、训练、推理时显存的变化情况)

7 参考链接


0 前言

本文为李宏毅学习笔记——2024春《GENERATIVE AI》篇——作业笔记HW4的补充内容4。

如果你还没获取到LLM API,请查看我的另一篇笔记:

HW1~2:LLM API获取步骤及LLM API使用演示:环境配置与多轮对话演示-CSDN博客

完整内容参见:

李宏毅学习笔记——2024春《GENERATIVE AI》篇

这篇文章将探讨两个重点:

  • 模型参数与显存(GPU 内存)之间的关系
  • 不同精度的导入方式,以及它们对显存和性能的影响

理解这些概念会让你在模型的选择上更加游刃有余。

强烈建议访问:

  • VRAM Estimator,交互式直观感受显存的组成
  • Model Memory Usage,选择模型查看显存使用

我之前的“手把手带你实战Transformers”学习笔记中"四:低精度训练篇"也介绍过模型训练时显存占用的分析、低精度训练以及如何降低训练时的显存占比,链接如下:

4.1 低精度训练与大模型下载-CSDN博客

​

1 模型参数与显存的关系

1.1 理论计算

神经网络模型由多个层组成,每一层都包含权重(weight)和偏置(bias),这些统称为模型参数。而模型的参数量一般直接影响它的学习和表示能力。

模型大小计算公式:

模型大小(字节)=参数数量×每个参数的字节数

示例:

对于一个拥有 10 亿(1,000,000,000) 参数的模型,使用 32 位浮点数(float32) 表示,每个参数占用 32/8=4 字节,即:

模型大小=1,000,000,000×4字节=4GB

具体来讲,以meta-llama/Meta-Llama-3.1-70B-Instruct 这个拥有 700 亿(70B) 参数的大模型为例,我们仅考虑模型参数,它的显存需求就已经超过了大多数消费级 GPU(如 RTX 4090 最高 48G):

70×109×4字节=280GB

简单来说: 1B=4GB

1.2 GPU显存需求

而在实际部署模型时,GPU 不仅需要容纳模型参数,还需要处理其他数据,这意味着更大的显存占用量。

训练时的显存占用

主要由以下部分组成:

  • 模型参数:模型的权重和偏置。
  • 优化器状态:如动量和二阶矩估计等,取决于优化器的类型,单纯的 SGD 不占显存。
    • Adam 优化器:需要存储一阶和二阶动量,各自占用模型参数大小的空间。
  • 梯度:每个参数对应一个梯度,数据类型与模型参数相同。
  • 中间激活值:前向传播过程中产生的激活值,需要在反向传播中使用,其显存占用与 Batch Size、序列长度以及模型架构相关。
  • 批量大小(Batch Size):一次处理的数据样本数量。
  • 其他开销:CUDA 上下文、显存碎片等。

举个例子:

以 1B 参数的模型为例,假设训练时使用 Adam,精度使用 FP32,仅考虑与模型参数挂钩的显存计算:

  • 模型参数:4 GB
  • 梯度:4 GB
  • 优化器状态(Adam:一阶和二阶动量):8 GB(2 × 4 GB)

总显存=4GB(参数)+4GB(梯度)+8GB(优化器状态)=16GB

推理时的显存占用

推理时的显存占用主要包括:

  • 模型参数:同训练阶段一致。
  • 中间激活值:仅保留当前步的激活值,相较于训练阶段,小非常多。
  • 批量大小(Batch Size):一次处理的数据样本数量。

举个例子:

  • 模型参数:4 GB

总显存=4GB(参数)

通过VRAM Estimator进行展示

  1. 对比 Training 和 Inference。

    image-20240922100157622

  2. 查看 fp16 和 fp32 下哪部分的显存会减小。

  3. 对比 Adam,SGD (Momentum) 以及 SGD。

  4. 逐一修改模型参数。

通过交互,你会印证一些想法,但可能会产生关于 Activations 激活值的疑惑。这篇文章讲述的是参数与显存的关系,所以 Activations 部分留待日后进行解释。

2 不同精度的导入方式及其影响

为了降低显存占用,我们可以使用不同的数值精度格式来存储模型参数,这些精度格式在内存使用和计算性能上各有优劣。

2.1 常见的数值精度格式

  • FP32(32 位浮点数):标准精度,每个参数占用 4 字节。

  • FP16(16 位浮点数):半精度浮点数,每个参数占用 2 字节。

  • BF16(16 位脑浮点数):与 FP16 类似,但具有更大的指数范围,适用于深度学习。

  • INT8(8 位整数):低精度整数,每个参数占用 1 字节。

  • 量化格式:4 位或更低,用于特殊的量化算法,进一步减少内存占用。

2.2 对精度占用的影响

使用更低的精度可以显著减少模型的内存占用:

  • FP16/BF16 相对于 FP32:内存占用减半。
  • INT8 相对于 FP32:内存占用减少到原来的四分之一。

示例:

对于一个 1B 参数的模型:

  • FP32 精度:4 GB 显存。
  • FP16/BF16 精度:2 GB 显存。
  • INT8 精度:1 GB 显存。

注意:实际显存占用还受到其他因素影响,如 CUDA 上下文、中间激活值和显存碎片等,因此不会严格按照理论值减半或减少四分之一。对于较小的模型,差距可能不会那么显著。

2.3 精度的权衡与选择

准确性 vs 性能

  • 高精度(FP32):

    • 优点:更高的数值稳定性和模型准确性。
    • 缺点:占用更多显存,计算速度较慢。
  • 低精度(FP16/INT8):

    • 优点:占用更少的显存,计算速度更快。
    • 缺点:可能引入数值误差,影响模型性能。

何时选择何种精度

  • FP32:适用于训练小型模型或对数值精度要求较高的任务。

  • FP16/BF16:适用于训练大型模型,利用混合精度(Mixed Precision)来节省显存并加速计算。

  • INT8:主要用于推理阶段,尤其是在显存资源有限的情况下部署超大模型。

2.4 硬件兼容性

  • FP16 支持:大多数现代 NVIDIA GPU(RTX 20 系列及以上)支持 FP16。

  • BF16 支持:BF16 支持在 NVIDIA Ampere 架构及以上的 GPU 上提供,包括 RTX 30 系列、RTX 40 系列以及 A100、H100 等数据中心级 GPU。

  • INT8 支持:使用 bitsandbytes 库,可以在大多数消费级 GPU 上实现 INT8 量化,无需特殊的硬件支持。

3 实际应用

3.1 使用FP16精度

1)PyTorch

PyTorch 提供了 torch.cuda.amp 模块,可以方便地实现混合精度训练,加速计算并降低显存占用。

  1. import torch
  2. from torch import nn, optim
  3. from torch.cuda.amp import GradScaler, autocast
  4. device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  5. model = nn.Sequential(...) # 定义模型
  6. model.to(device)
  7. optimizer = optim.Adam(model.parameters(), lr=1e-3)
  8. scaler = GradScaler() # 初始化梯度缩放器
  9. for data, labels in dataloader:
  10. data = data.to(device)
  11. labels = labels.to(device)
  12. optimizer.zero_grad()
  13. with autocast(): # 启用混合精度,默认 FP16
  14. outputs = model(data)
  15. loss = criterion(outputs, labels)
  16. # 使用梯度缩放器进行反向传播
  17. scaler.scale(loss).backward()
  18. scaler.step(optimizer)
  19. scaler.update()

推理

  1. model.half() # 将模型转换为 FP16
  2. model.to(device)
  3. inputs = inputs.half().to('cuda')
  4. outputs = model(inputs)

2)Hugging Face Accelerate

如果你使用 Hugging Face 的模型,可以直接使用 Accelerate 库。

  1. from accelerate import Accelerator
  2. # 初始化 Accelerator,开启混合精度
  3. accelerator = Accelerator(fp16=True)
  4. model = ... # 定义模型
  5. optimizer = ... # 定义优化器
  6. dataloader = ... # 定义数据加载器
  7. # 使用 accelerator.prepare() 函数包装模型、优化器和数据加载器
  8. model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)
  9. for data, labels in dataloader:
  10. outputs = model(data)
  11. loss = loss_fn(outputs, labels)
  12. # 使用 accelerator 进行反向传播和优化步骤
  13. accelerator.backward(loss)
  14. optimizer.step()
  15. optimizer.zero_grad()

3.2 使用BF16精度

1)PyTorch

  1. with autocast(dtype=torch.bfloat16): # 手动启用 BF16
  2. outputs = model(data)
  3. loss = criterion(outputs, labels)
  4. ...

推理:

  1. model = model.to(torch.bfloat16).to(device)
  2. inputs = inputs.to(torch.bfloat16).to(device)
  3. outputs = model(inputs)

2)Hugging Face Accelerate

  1. from accelerate import Accelerator
  2. # 初始化 Accelerator,开启 BF16 混合精度
  3. accelerator = Accelerator(mixed_precision="bf16") # 启用 BF16 精度
  4. model = ... # 定义模型
  5. optimizer = ... # 定义优化器
  6. dataloader = ... # 定义数据加载器
  7. # 使用 accelerator.prepare() 函数包装模型、优化器和数据加载器
  8. model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)
  9. for data, labels in dataloader:
  10. outputs = model(data)
  11. loss = loss_fn(outputs, labels)
  12. # 使用 accelerator 进行反向传播和优化步骤
  13. accelerator.backward(loss)
  14. optimizer.step()
  15. optimizer.zero_grad()

3.3 使用INT8量化

安装 bitsandbytes

!pip install bitsandbytes

使用 bitsandbytes 库实现 INT8 量化

  1. from transformers import AutoModelForCausalLM
  2. import bitsandbytes as bnb
  3. model_name = 'gpt2-large'
  4. model = AutoModelForCausalLM.from_pretrained(
  5. model_name,
  6. load_in_8bit=True,
  7. device_map='auto'
  8. )

消除警告:

在加载模型时,可能会遇到以下警告:

The load_in_4bit and load_in_8bit arguments are deprecated and will be removed in the future versions. Please, pass a BitsAndBytesConfig object in quantization_config argument instead.

解决方法:

使用 BitsAndBytesConfig 对象来配置量化参数。

  1. from transformers import AutoModelForCausalLM, BitsAndBytesConfig
  2. bnb_config = BitsAndBytesConfig(load_in_8bit=True)
  3. model = AutoModelForCausalLM.from_pretrained(
  4. model_name,
  5. quantization_config=bnb_config,
  6. device_map='auto'
  7. )

3.4 实践示例

对比不同精度下的显存占用

加载模型并查看显存占用

以下代码示例展示了在不同精度下加载 gpt2-large 模型时的显存占用情况。gpt2-large 大约有 812M(8.12 亿)= 0.812B 个参数。

  1. import os
  2. import gc
  3. import torch
  4. from transformers import AutoModelForCausalLM, BitsAndBytesConfig
  5. import bitsandbytes as bnb
  6. def load_model_and_measure_memory(precision, model_name, device):
  7. if precision == 'fp32':
  8. model = AutoModelForCausalLM.from_pretrained(model_name).to(device)
  9. elif precision == 'fp16':
  10. model = AutoModelForCausalLM.from_pretrained(
  11. model_name,
  12. torch_dtype=torch.float16,
  13. low_cpu_mem_usage=True
  14. ).to(device)
  15. elif precision == 'int8':
  16. bnb_config = BitsAndBytesConfig(load_in_8bit=True)
  17. model = AutoModelForCausalLM.from_pretrained(
  18. model_name,
  19. quantization_config=bnb_config,
  20. device_map='auto'
  21. )
  22. else:
  23. raise ValueError("Unsupported precision")
  24. # 确保所有 CUDA 操作完成
  25. torch.cuda.synchronize()
  26. mem_allocated = torch.cuda.memory_allocated(device) / 1e9
  27. print(f"Precision: {precision}, Memory Allocated after loading model: {mem_allocated:.2f} GB")
  28. # 删除模型并清理缓存
  29. del model
  30. gc.collect()
  31. torch.cuda.empty_cache()
  32. device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  33. model_name = 'gpt2-large'
  34. for precision in ['fp32', 'fp16', 'int8']:
  35. print(f"\n--- Loading model with precision: {precision} ---")
  36. load_model_and_measure_memory(precision, model_name, device)

示例输出:

  1. --- Loading model with precision: fp32 ---
  2. Precision: fp32, Memory Allocated after loading model: 3.21 GB
  3. --- Loading model with precision: fp16 ---
  4. Precision: fp16, Memory Allocated after loading model: 1.60 GB
  5. --- Loading model with precision: int8 ---
  6. Precision: int8, Memory Allocated after loading model: 0.89 GB

额外说明:

torch.cuda.memory_allocated 仅测量由 PyTorch 当前进程分配的显存,不包括其他进程或系统预留的显存。

4 常见问题及解决方案

4.1 问题一:RuntimeError解决方法

RuntimeError: Failed to import transformers.models.gpt2.modeling_gpt2 because of the following error (look up to see its traceback): module 'wandb.proto.wandb_internal_pb2' has no attribute 'Result'

解决方法:

卸载并重新安装 wandb:

  1. pip uninstall wandb
  2. pip install wandb

如果问题仍然存在,禁用 wandb:

  1. import os
  2. os.environ["WANDB_DISABLED"] = "true"

4.2 问题二:TypeError解决方法

解决方法:

检查 transformers 和 accelerate 库的版本:

  1. import transformers
  2. import accelerate
  3. print(f"Transformers version: {transformers.__version__}")
  4. print(f"Accelerate version: {accelerate.__version__}")

更新库:

pip install --upgrade transformers accelerate

5 总结

现在你应该理解了模型参数与显存的关系,以及不同数值精度对显存和性能的影响,这不仅在实际应用中具有重要意义,也是面试中的常见考点,而且对于后续的学习同样很重要。毕竟看得懂代码在说什么,比当作黑箱要好得多,知道精度的概念会让你在模型的选择上更加游刃有余。

最后的思考:

精度的降低意味着性能的妥协,在我过去的一些小型试验中(非 LLM),低精度下训练的性能还是一般都不如高精度。但,跑不跑的好是一回事,能不能跑又是另一回事,如果低显存能跑大模型,性能上的妥协也是完全可以接受的。

该图展示了在 wikitext 数据集上,不同模型大小(以 GiB 为单位)与其 PPL (Perplexity,PPL)之间的关系。横轴为模型大小(对数尺度),纵轴为 PPL 。图中的不同颜色代表不同大小的 LLaMA 模型(黑色 7B、红色 13B、蓝色 30B、品红 65B),相应颜色的正方形表示原始的FP16模型。

PPL 衡量的是一个语言模型对测试数据的预测能力,数值越小,表示模型对语言的理解和预测越好。它可以理解为模型在给定上下文的情况下,预测下一个词的困难度。

从图中可以看出, PPL 基本上是模型大小的平滑函数。也就是说,通过调整量化策略,我们可以在模型大小和性能之间找到一个平衡点。在计算资源有限的情况下(例如内存或显存限制),新的量化方法允许我们选择最适合的模型(这个工作做得真好)。

值得注意的是,6-bit 量化模型的 PPL 与原始 fp16 模型的差异在 0.1% 以内或者更好,性能几乎没有损失。

6 完整例子(解释模型在加载、训练、推理时显存的变化情况)

这里定义一个简单的线性层进行模拟,展示导入,训练和推理阶段显存的变化:

  1. import torch
  2. import torch.nn as nn
  3. import torch.optim as optim
  4. from torchvision import datasets, transforms
  5. import gc
  6. import matplotlib.pyplot as plt
  7. device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
  8. # 定义一个简单的多层感知机(MLP)
  9. class SimpleMLP(nn.Module):
  10. def __init__(self):
  11. super(SimpleMLP, self).__init__()
  12. self.layers = nn.Sequential(
  13. nn.Linear(28 * 28, 8192),
  14. nn.ReLU(),
  15. nn.Linear(8192, 4096),
  16. nn.ReLU(),
  17. nn.Linear(4096, 2048),
  18. nn.ReLU(),
  19. nn.Linear(2048, 1024),
  20. nn.ReLU(),
  21. nn.Linear(1024, 512),
  22. nn.ReLU(),
  23. nn.Linear(512, 10)
  24. )
  25. def forward(self, x):
  26. x = x.view(x.size(0), -1) # 展平输入
  27. x = self.layers(x)
  28. return x
  29. # 准备数据集(使用 MNIST)
  30. transform = transforms.Compose([
  31. transforms.ToTensor(),
  32. transforms.Normalize((0.1307,), (0.3081,))
  33. ])
  34. batch_size = 128
  35. train_dataset = datasets.MNIST('./data', train=True, download=True, transform=transform)
  36. train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
  37. test_dataset = datasets.MNIST('./data', train=False, download=True, transform=transform)
  38. test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
  39. # 函数:仅测量已分配的显存
  40. def print_gpu_memory(stage):
  41. torch.cuda.empty_cache()
  42. allocated = torch.cuda.memory_allocated(device) / 1e6 # 已分配显存
  43. print(f'[{stage}] Allocated: {allocated:.2f} MB')
  44. # 清理缓存,确保测量准确
  45. torch.cuda.empty_cache()
  46. gc.collect()
  47. # ---------------------------
  48. # 1. 测量导入模型时的显存占用
  49. # ---------------------------
  50. print('Measuring memory usage during model loading...')
  51. print_gpu_memory('Before loading model')
  52. model = SimpleMLP().to(device)
  53. print_gpu_memory('After loading model')
  54. # 保存导入阶段的显存占用
  55. memory_loading = torch.cuda.memory_allocated(device) / 1e6
  56. # ---------------------------
  57. # 2. 测量训练过程中的显存占用,并计算数据占用的显存
  58. # ---------------------------
  59. print('\nMeasuring memory usage during training...')
  60. criterion = nn.CrossEntropyLoss()
  61. optimizer = optim.Adam(model.parameters(), lr=0.001) # 你可以切换成 SGD 查看区别
  62. num_epochs = 1 # 为了快速演示,只训练一个 epoch
  63. print_gpu_memory('Before training')
  64. model.train()
  65. for epoch in range(num_epochs):
  66. for batch_idx, (data, target) in enumerate(train_loader):
  67. # 记录数据加载到 GPU 前的显存使用情况
  68. memory_before_data = torch.cuda.memory_allocated(device) / 1e6
  69. data, target = data.to(device), target.to(device)
  70. # 记录数据加载到 GPU 后的显存使用情况
  71. memory_after_data = torch.cuda.memory_allocated(device) / 1e6
  72. data_memory_usage = memory_after_data - memory_before_data
  73. print(f'Data memory usage for batch {batch_idx + 1}: {data_memory_usage:.2f} MB')
  74. # 记录训练开始前的显存
  75. memory_before_training_step = torch.cuda.memory_allocated(device) / 1e6
  76. optimizer.zero_grad()
  77. output = model(data)
  78. loss = criterion(output, target)
  79. loss.backward()
  80. optimizer.step()
  81. # 训练结束后的显存
  82. memory_after_training_step = torch.cuda.memory_allocated(device) / 1e6
  83. # 计算训练步骤中的额外显存占用(激活值、梯度、优化器状态等)
  84. training_step_memory_usage = memory_after_training_step - memory_before_training_step
  85. print(f'Training step memory usage: {training_step_memory_usage:.2f} MB')
  86. # 只测量一次
  87. if batch_idx == 0:
  88. print_gpu_memory(f'Training Epoch {epoch+1}, Batch {batch_idx+1}')
  89. # 保存训练阶段的显存占用
  90. memory_training = torch.cuda.memory_allocated(device) / 1e6
  91. break
  92. # ---------------------------
  93. # 3. 测量推理过程中的显存占用,并计算数据占用的显存
  94. # ---------------------------
  95. print('\nMeasuring memory usage during inference...')
  96. # 在推理前清理训练相关的变量和缓存
  97. del optimizer
  98. del criterion
  99. # 清理所有模型参数的梯度
  100. for param in model.parameters():
  101. param.grad = None
  102. torch.cuda.empty_cache()
  103. gc.collect()
  104. model.eval()
  105. with torch.no_grad():
  106. for batch_idx, (data, target) in enumerate(test_loader):
  107. # 记录数据加载到 GPU 前的显存使用情况
  108. memory_before_data = torch.cuda.memory_allocated(device) / 1e6
  109. data = data.to(device)
  110. # 记录数据加载到 GPU 后的显存使用情况
  111. memory_after_data = torch.cuda.memory_allocated(device) / 1e6
  112. data_memory_usage = memory_after_data - memory_before_data
  113. print(f'Data memory usage for inference batch {batch_idx + 1}: {data_memory_usage:.2f} MB')
  114. output = model(data)
  115. # 只测量一次
  116. if batch_idx == 0:
  117. print_gpu_memory(f'Inference Batch {batch_idx+1}')
  118. # 保存推理阶段的显存占用
  119. memory_inference = torch.cuda.memory_allocated(device) / 1e6
  120. break
  121. # ---------------------------
  122. # 4. 整理并展示结果
  123. # ---------------------------
  124. print('\nSummary of GPU Memory Usage:')
  125. print(f'Memory during model loading: {memory_loading:.2f} MB')
  126. print(f'Memory during training: {memory_training:.2f} MB')
  127. print(f'Memory during inference: {memory_inference:.2f} MB')
  128. # 可视化
  129. stages = ['Loading', 'Training', 'Inference']
  130. memories = [memory_loading, memory_training, memory_inference]
  131. plt.bar(stages, memories, color=['blue', 'green', 'red'])
  132. plt.ylabel('GPU Memory Usage (MB)')
  133. plt.title('GPU Memory Usage at Different Stages')
  134. plt.show()

输出:

  1. Measuring memory usage during model loading...
  2. [Before loading model] Allocated: 0.00 MB
  3. [After loading model] Allocated: 204.03 MB
  4. Measuring memory usage during training...
  5. [Before training] Allocated: 204.03 MB
  6. Data memory usage for batch 1: 0.40 MB
  7. Training step memory usage: 425.11 MB
  8. [Training Epoch 1, Batch 1] Allocated: 629.54 MB
  9. Measuring memory usage during inference...
  10. Data memory usage for inference batch 1: 0.40 MB
  11. [Inference Batch 1] Allocated: 221.48 MB
  12. Summary of GPU Memory Usage:
  13. Memory during model loading: 204.03 MB
  14. Memory during training: 629.54 MB
  15. Memory during inference: 221.48 MB

可以看到=显存占比(加载:训练:推理)约为 1 : 4 : 1。

因为训练时,Adam 占了 2 倍大小的模型参数显存,梯度占了 1 倍。你可以修改代码中的 Adam 为 SGD,此时的输出如下:

  1. Measuring memory usage during model loading...
  2. [Before loading model] Allocated: 0.00 MB
  3. [After loading model] Allocated: 204.03 MB
  4. Measuring memory usage during training...
  5. [Before training] Allocated: 204.03 MB
  6. Data memory usage for batch 1: 0.40 MB
  7. Training step memory usage: 221.08 MB
  8. [Training Epoch 1, Batch 1] Allocated: 425.51 MB
  9. Measuring memory usage during inference...
  10. Data memory usage for inference batch 1: 0.40 MB
  11. [Inference Batch 1] Allocated: 221.48 MB
  12. Summary of GPU Memory Usage:
  13. Memory during model loading: 204.03 MB
  14. Memory during training: 425.51 MB
  15. Memory during inference: 221.48 MB

在不存储动量信息后,占比变为了 1 : 2 : 1。

7 参考链接

  • PyTorch Mixed Precision Training
  • Transformers Documentation
  • bitsandbytes - Github
注:本文转载自blog.csdn.net的笨笨sg的文章"https://blog.csdn.net/a131529/article/details/144186774"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top