1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| import torch import torch.nn as nn
class ModelQuantizer: """ 模型量化工具 INT8量化压缩模型大小 """ def __init__(self, model: nn.Module): self.model = model self.quantized_model = None def quantize_dynamic(self) -> nn.Module: """ 动态量化 权重量化为INT8,激活保持FP32 """ self.quantized_model = torch.quantization.quantize_dynamic( self.model, {nn.Linear, nn.Conv2d}, dtype=torch.qint8 ) return self.quantized_model def quantize_static( self, calibration_data: torch.Tensor ) -> nn.Module: """ 静态量化 权重和激活都量化为INT8 """ self.model.qconfig = torch.quantization.get_default_qconfig('fbgemm') self.model = torch.quantization.fuse_modules( self.model, [['conv', 'bn', 'relu']] ) torch.quantization.prepare(self.model, inplace=True) with torch.no_grad(): self.model(calibration_data) self.quantized_model = torch.quantization.convert(self.model) return self.quantized_model def compare_size(self) -> dict: """比较模型大小""" import os import tempfile with tempfile.NamedTemporaryFile() as f: torch.save(self.model.state_dict(), f.name) original_size = os.path.getsize(f.name) with tempfile.NamedTemporaryFile() as f: torch.save(self.quantized_model.state_dict(), f.name) quantized_size = os.path.getsize(f.name) return { 'original_size_mb': original_size / 1024 / 1024, 'quantized_size_mb': quantized_size / 1024 / 1024, 'compression_ratio': original_size / quantized_size }
if __name__ == "__main__": model = nn.Sequential( nn.Conv2d(3, 64, 3, padding=1), nn.ReLU(), nn.Conv2d(64, 128, 3, padding=1), nn.ReLU(), nn.AdaptiveAvgPool2d(1), nn.Flatten(), nn.Linear(128, 10) ) quantizer = ModelQuantizer(model) quantized = quantizer.quantize_dynamic() size_info = quantizer.compare_size() print(f"原始模型大小: {size_info['original_size_mb']:.2f} MB") print(f"量化后大小: {size_info['quantized_size_mb']:.2f} MB") print(f"压缩比: {size_info['compression_ratio']:.2f}x")
|