PyTorch LSTM Word 語言模型上的(實驗)動態(tài)量化

2025-06-23 11:58 更新

在自然語言處理任務中,模型的性能和效率至關重要。動態(tài)量化是一種有效的技術,可以減小模型尺寸、加快推斷速度,同時對模型準確性影響較小。本教程將詳細講解如何在 LSTM Word 語言模型上應用動態(tài)量化。

一、模型定義

我們首先定義一個基于 LSTM 的語言模型,該模型包括編碼器、循環(huán)模塊和解碼器。

import torch
import torch.nn as nn
import torch.nn.functional as F


class LSTMModel(nn.Module):
    """包含編碼器、循環(huán)模塊和解碼器的容器模塊。"""


    def __init__(self, ntoken, ninp, nhid, nlayers, dropout=0.5):
        super(LSTMModel, self).__init__()
        self.drop = nn.Dropout(dropout)
        self.encoder = nn.Embedding(ntoken, ninp)
        self.rnn = nn.LSTM(ninp, nhid, nlayers, dropout=dropout)
        self.decoder = nn.Linear(nhid, ntoken)
        self.init_weights()
        self.nhid = nhid
        self.nlayers = nlayers


    def init_weights(self):
        initrange = 0.1
        self.encoder.weight.data.uniform_(-initrange, initrange)
        self.decoder.bias.data.zero_()
        self.decoder.weight.data.uniform_(-initrange, initrange)


    def forward(self, input, hidden):
        emb = self.drop(self.encoder(input))
        output, hidden = self.rnn(emb, hidden)
        output = self.drop(output)
        decoded = self.decoder(output)
        return decoded, hidden


    def init_hidden(self, bsz):
        weight = next(self.parameters())
        return (weight.new_zeros(self.nlayers, bsz, self.nhid),
                weight.new_zeros(self.nlayers, bsz, self.nhid))

二、數據預處理

我們將使用 Wikitext-2 數據集來訓練和評估模型。首先,我們需要對數據進行預處理,包括分詞和轉換為張量。

class Dictionary(object):
    def __init__(self):
        self.word2idx = {}
        self.idx2word = []


    def add_word(self, word):
        if word not in self.word2idx:
            self.idx2word.append(word)
            self.word2idx[word] = len(self.idx2word) - 1
        return self.word2idx[word]


    def __len__(self):
        return len(self.idx2word)


class Corpus(object):
    def __init__(self, path):
        self.dictionary = Dictionary()
        self.train = self.tokenize(os.path.join(path, 'train.txt'))
        self.valid = self.tokenize(os.path.join(path, 'valid.txt'))
        self.test = self.tokenize(os.path.join(path, 'test.txt'))


    def tokenize(self, path):
        """對文本文件進行分詞。"""
        assert os.path.exists(path)
        with open(path, 'r', encoding="utf8") as f:
            for line in f:
                words = line.split() + ['<eos>']
                for word in words:
                    self.dictionary.add_word(word)
        with open(path, 'r', encoding="utf8") as f:
            idss = []
            for line in f:
                words = line.split() + ['<eos>']
                ids = []
                for word in words:
                    ids.append(self.dictionary.word2idx[word])
                idss.append(torch.tensor(ids).type(torch.int64))
            ids = torch.cat(idss)
        return ids


model_data_filepath = 'data/'
corpus = Corpus(model_data_filepath + 'wikitext-2')

三、加載預訓練模型

為了應用動態(tài)量化,我們首先需要加載預訓練的模型權重。

ntokens = len(corpus.dictionary)
model = LSTMModel(
    ntoken=ntokens,
    ninp=512,
    nhid=256,
    nlayers=5,
)
model.load_state_dict(
    torch.load(
        model_data_filepath + 'word_language_model_quantize.pth',
        map_location=torch.device('cpu')
    )
)
model.eval()
print(model)

四、動態(tài)量化應用

使用 PyTorch 的 quantize_dynamic 函數對模型進行動態(tài)量化。

import torch.quantization


quantized_model = torch.quantization.quantize_dynamic(
    model, {nn.LSTM, nn.Linear}, dtype=torch.qint8
)
print(quantized_model)

五、性能評估

比較量化前后模型的大小和推斷速度。

def print_size_of_model(model):
    torch.save(model.state_dict(), "temp.p")
    print('Size (MB):', os.path.getsize("temp.p") / 1e6)
    os.remove('temp.p')


print_size_of_model(model)
print_size_of_model(quantized_model)

測試模型的推斷性能:

torch.set_num_threads(1)


def time_model_evaluation(model, test_data):
    s = time.time()
    loss = evaluate(model, test_data)
    elapsed = time.time() - s
    print('''loss: {0:.3f}
elapsed time (seconds): {1:.1f}'''.format(loss, elapsed))


time_model_evaluation(model, test_data)
time_model_evaluation(quantized_model, test_data)

六、結果分析

通過動態(tài)量化,我們可以看到模型尺寸明顯減小,推斷速度顯著提高,而模型的準確性幾乎沒有受到影響。在實際應用中,這種優(yōu)化對于模型的部署和推理效率提升具有重要意義。

在編程獅(W3Cschool)平臺上,你可以找到更多關于 PyTorch 模型優(yōu)化和動態(tài)量化的詳細教程和示例代碼,幫助你深入理解和應用這些技術。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號