IT评测·应用市场-qidao123.com

标题: 特定transfomer架构的模型的压缩量化处理 [打印本页]

作者: 滴水恩情    时间: 2025-3-5 19:55
标题: 特定transfomer架构的模型的压缩量化处理
〇、媒介

近来在做大模型压缩这一块,我感觉从拿到一个模型,到选取一个对象选取一种压缩方法,最后查看压缩的结果,这应该算是一次完整的流程了。
一、模型的选择

Transformer、LLaMA、BERT、GPT 之间既有精密联系,也有显著区别。它们都是基于 Transformer 的架构,但在设计、使命、预练习方式和应用场景上有所不同。
1. Transformer

特点:

应用:
Transformer 是后续浩繁模型的基础架构,包括 BERT、GPT、T5 等。它的自注意力机制使得模型可以或许更有效地处理长文本序列,并在多个 NLP 使命中体现精彩。
2. BERT(Bidirectional Encoder Representations from Transformers)

特点:

应用:
BERT 被广泛用于各种 文本明白 使命,如分类、问答、命名实体辨认(NER)等。它并不擅永生成使命,因为它只使用了 Transformer 的编码器部分,无法生成新的文本。
联系:

3. GPT(Generative Pretrained Transformer)

特点:

应用:
GPT 系列模型尤其善于 文本生成使命,如对话生成、机器翻译、文本补全、编写文章等。GPT 也可以应用于部分文本明白使命,但其设计初志主要是为了生成使命。
联系:

4. LLaMA(Large Language Model Meta AI)

特点:

应用:
LLaMA 主要用于 文本生成使命,类似于 GPT 系列的应用场景,但其目标是在较小的参数规模下提供与更大模型相似的性能。由于其较小的模型规模,LLaMA 更适合研究人员进行探索性研究。
联系:

5. 总结:各个transfomer架构模型区别与联系表格整理

模型架构使命类型预练习方式主要应用Transformer编码器-解码器通用架构N/ANLP 和 CV 使命的基础架构BERT编码器文本明白(分类、问答等)Masked Language Model (MLM) 和 Next Sentence Prediction (NSP)文本明白使命,特别是分类和问答GPT解码器文本生成语言模型(LM)预练习文本生成使命,如对话生成、文章生成LLaMA解码器文本生成自回归语言模型文本生成,强调轻量化大模型 a.主要联系:架构基础相同+注意力机制


b.主要区别:仅编码、仅解码、编码和解码


二、压缩的对象

在深度学习模型的练习和推理阶段需要保存或使用的不同类型的对象。
1. 练习阶段:梯度、优化器

在练习时,模型通过盘算梯度和调解模型参数来学习和优化。

2.推理阶段:权重、激活、KV Cache

在推理时,模型的目标是基于给定输入生成输出,不再进行梯度盘算,而是使用预练习好的权重和缓存。

三、压缩的方法

PTQ(Post-Training Quantization)QAT(Quantization-Aware Training) 是两种常见的量化(Quantization)方法,它们的目标是通过淘汰模型的数值精度来压缩模型大小、加快推理速率,并淘汰盘算资源的消耗,尤其在移动装备或嵌入式装备上。它们的主要区别在于 量化发生的机遇如那边理量化偏差
1. PTQ(Post-Training Quantization)

后练习量化 是指在模型练习完成之后对模型进行量化。它不需要在练习期间考虑量化问题,只在练习后进行处理。
特点:

工作流程:
优势:

劣势:

2. QAT(Quantization-Aware Training)

量化感知练习 是指在模型练习的过程中模拟量化过程,使得模型可以或许感知量化的影响,并调解参数以适应量化后的推理。
特点:

工作流程:
优势:

劣势:

3.PTQ 和 QAT 的对比表格整理

特性PTQ(Post-Training Quantization)QAT(Quantization-Aware Training)量化机遇在模型练习完成后进行量化在练习过程中模拟量化实现难度简朴,练习后直接量化较复杂,需在练习中进行量化模拟练习本钱无需重新练习,练习本钱低需要重新练习,练习本钱高精度丧失可能较大,尤其是复杂使命精度丧失较小,模型适应量化偏差适用场景对精度要求不高的场景对精度要求较高的场景模型类型预练习的浮点模型量化感知模型 4.选择哪种量化方法?


四、压缩的结果

大模型压缩的结果评估涉及多个维度,不仅需要考虑模型压缩后在存储和盘算资源上的节流,还要衡量模型在推理性能、速率和准确性上的体现。常见的大模型压缩结果评估指标可以分为以下几类:
1. 模型性能指标

模型压缩后最重要的是确保其性能不会大幅降落,因此常用的模型性能评估指标包括:

- F1 值(F1 Score)

- BLEU、ROUGE 分数

- 均方偏差(MSE)

2. 模型尺寸和存储效率

压缩模型的一个主要目标是淘汰其存储空间。以下指标可以用于评估模型压缩带来的存储优化结果:

3. 推理速率

压缩后的模型是否能显著加速推理过程,是评估其结果的一个重要指标,特别是在资源受限的装备上。

4. 能耗和资源使用效率

在现实部署中,特别是移动装备或嵌入式装备中,评估压缩后的模型资源使用效率至关重要。

5. 压缩比例

这个指标用来直接量化压缩的结果,通常包括以下几类:

6. 压缩对比实验

为了评估压缩结果,通常需要进行对比实验,包括以下方式:

7.感知质量(Perceptual Quality)

对于涉及图像、视频、语音等生成使命的模型,感知质量是重要的评估指标,主要通过人类的主观感知或基于模型的感知丧失函数来衡量。

五、示例:以Llama-7B的中文版本为例

1.原理:

LLM.int8(): Int8 矩阵乘法来处理 Transformer 模型中的前馈层(Feed Forward)和注意力投影层(Multi-HeadAttention),从而将推理所需的内存减半,同时保持完整精度的性能。

2.使用源码

  1. import torch
  2. import torch.nn as nn
  3. import os
  4. import time
  5. from modelscope import AutoTokenizer
  6. from transformers import LlamaForCausalLM
  7. import bitsandbytes as bnb
  8. import random
  9. import numpy as np
  10. random.seed(42)
  11. np.random.seed(42)
  12. torch.manual_seed(42)
  13. def redirect_output_to_file(file_path):
  14.     import sys
  15.     sys.stdout = open(file_path, 'w')
  16. output_file = os.path.join(os.getcwd(), 'LLMint8_try_output.txt')
  17. redirect_output_to_file(output_file)
  18. model_dir = '/home/mshw/model/Llama2-Chinese-7b-Chat-ms'
  19. print(model_dir)
  20. if not torch.cuda.is_available():
  21.     raise RuntimeError("CUDA 不可用,请检查 GPU 配置")
  22. n_gpus = torch.cuda.device_count()
  23. print(f"Number of GPUs detected: {n_gpus}")
  24. if n_gpus == 0:
  25.     raise RuntimeError("没有检测到可用的 GPU")
  26. max_memory = {}
  27. for i in range(n_gpus):
  28.     free_mem, total_mem = torch.cuda.mem_get_info(i)
  29.     max_mem_gb = max(0, int(free_mem / 1024**3) - 1)
  30.     max_memory[i] = f"{max_mem_gb}GB"
  31.     print(f"GPU {i}: {max_mem_gb}GB free memory allocated for usage.")
  32. cache_dir = os.getcwd()
  33. offload_folder = os.path.join(cache_dir, 'offload')
  34. os.makedirs(offload_folder, exist_ok=True)
  35. # 加载模型
  36. model = LlamaForCausalLM.from_pretrained(model_dir, torch_dtype=torch.float16, device_map='auto')
  37. # 确保模型权重绑定
  38. model.tie_weights()
  39. tokenizer = AutoTokenizer.from_pretrained(model_dir, cache_dir=cache_dir)
  40. def get_sparsity(tensor: torch.Tensor) -> float:
  41.     tensor_cpu = tensor.to('cpu')
  42.     return 1 - float(tensor_cpu.count_nonzero()) / tensor_cpu.numel()
  43. def get_num_parameters(model: nn.Module, count_nonzero_only=False) -> int:
  44.     num_counted_elements = 0
  45.     for param in model.parameters():
  46.         if count_nonzero_only:
  47.             param_cpu = param.detach().to('cpu')
  48.             num_counted_elements += param_cpu.count_nonzero()
  49.         else:
  50.             num_counted_elements += param.numel()
  51.     return num_counted_elements
  52. def get_model_size_in_gb(model: nn.Module, data_width=8, count_nonzero_only=False) -> float:
  53.     data_width_bytes = data_width // 8
  54.     model_size_bytes = get_num_parameters(model, count_nonzero_only) * data_width_bytes
  55.     model_size_gb = model_size_bytes / (1024**3)
  56.     return model_size_gb
  57. def calculate_memory_access(tensor: torch.Tensor) -> int:
  58.     return tensor.numel() * tensor.element_size()
  59. def get_model_memory_access(model: nn.Module) -> int:
  60.     total_access = 0
  61.     for param in model.parameters():
  62.         total_access += calculate_memory_access(param)
  63.     return total_access
  64. # 使用8位宽度进行模型大小计算
  65. model_size_gb = get_model_size_in_gb(model, data_width=8)
  66. inputs = "咖啡的作用是什么?"
  67. MiB = 1024 * 1024
  68. torch.cuda.reset_peak_memory_stats()
  69. start_time = time.time()
  70. # 使用适当的方法进行推理
  71. inputs_encoded = tokenizer(inputs, return_tensors='pt').to('cuda')
  72. inputs_encoded.pop("token_type_ids", None)  # 移除不需要的键
  73. outputs = model.generate(**inputs_encoded)
  74. result = tokenizer.decode(outputs[0], skip_special_tokens=True)
  75. end_time = time.time()
  76. for i in range(n_gpus):
  77.     peak_mem = torch.cuda.max_memory_reserved(device=i) / MiB
  78.     print(f"GPU {i} 峰值内存: {peak_mem:.2f} MiB")
  79. print(result)
  80. print(f"推理时间: {end_time - start_time:.2f} 秒")
  81. # 恢复标准输出
  82. import sys
  83. sys.stdout.close()
  84. sys.stdout = sys.__stdout__
复制代码

3.思考

怎么区分权重的异常特征和正常特征?

均值和尺度差:盘算每层权重的均值和尺度差,辨认那些偏离较大的权重
设定合理阈值:界说上下限,找出超出范围的权重。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4