Este repositório contém o código usado para dois artigos da Salesforce Research:
O modelo vem com instruções para treinar:
modelos de linguagem em nível de palavra nos conjuntos de dados Penn Treebank (PTB), WikiText-2 (WT2) e WikiText-103 (WT103)
modelos de linguagem em nível de personagem sobre o conjunto de dados Penn Treebank (PTBC) e Hutter Prize (enwik8)
O modelo pode ser composto por um LSTM ou uma Rede Neural Quase Recorrente (QRNN) que é duas ou mais vezes mais rápida que o cuDNN LSTM nesta configuração, ao mesmo tempo que alcança precisão equivalente ou melhor.
getdata.sh
para adquirir os conjuntos de dados Penn Treebank e WikiText-2main.py
finetune.py
pointer.py
Se você usar este código ou nossos resultados em sua pesquisa, cite conforme apropriado:
@article{merityRegOpt,
title={{Regularizing and Optimizing LSTM Language Models}},
author={Merity, Stephen and Keskar, Nitish Shirish and Socher, Richard},
journal={arXiv preprint arXiv:1708.02182},
year={2017}
}
@article{merityAnalysis,
title={{An Analysis of Neural Language Modeling at Multiple Scales}},
author={Merity, Stephen and Keskar, Nitish Shirish and Socher, Richard},
journal={arXiv preprint arXiv:1803.08240},
year={2018}
}
A base de código agora é compatível com PyTorch 0.4 para a maioria dos casos de uso (uma grande mensagem para https://github.com/shawntan para um PR # 43 bastante abrangente). Podem ser necessários reajustes leves nos hiperparâmetros para obter o desempenho cotado. Se você deseja reprodutibilidade exata (ou deseja rodar no PyTorch 0.3 ou inferior), sugerimos usar um commit mais antigo deste repositório. Ainda estamos trabalhando em funcionalidades pointer
, finetune
e generate
.
Python 3 e PyTorch 0.4 são necessários para a base de código atual.
Abaixo estão incluídos hiperparâmetros para obter resultados equivalentes ou melhores aos incluídos no artigo original.
Se você precisar usar uma versão anterior da base de código, o código original e os hiperparâmetros acessíveis na versão PyTorch==0.1.12, com Python 3 e PyTorch 0.1.12 são necessários. Se você estiver usando o Anaconda, a instalação do PyTorch 0.1.12 pode ser feita via: conda install pytorch=0.1.12 -c soumith
.
A base de código foi modificada durante a redação do artigo, impedindo a reprodução exata devido a pequenas diferenças em sementes aleatórias ou similares. Também vimos os números exatos de reprodução mudarem ao alterar a GPU subjacente. O guia abaixo produz resultados muito semelhantes aos números relatados.
Para configuração de dados, execute ./getdata.sh
. Este script coleta os conjuntos de dados Penn Treebank pré-processados de Mikolov e WikiText-2 e os coloca no diretório data
.
Em seguida, decida se deseja usar o QRNN ou o LSTM como modelo de rede neural recorrente subjacente. O QRNN é muitas vezes mais rápido do que o LSTM otimizado para cuDNN da Nvidia (e dezenas de vezes mais rápido do que uma implementação LSTM ingênua), mas alcança resultados semelhantes ou melhores do que o LSTM para muitos conjuntos de dados em nível de palavra. No momento em que este artigo foi escrito, os modelos QRNN usavam o mesmo número de parâmetros e eram redes um pouco mais profundas, mas eram duas a quatro vezes mais rápidas por época e exigiam menos épocas para convergir.
O modelo QRNN usa um QRNN com tamanho convolucional 2 para a primeira camada, permitindo que o modelo visualize entradas discretas de linguagem natural (ou seja, "Nova York"), enquanto todas as outras camadas usam um tamanho convolucional de 1.
Nota de ajuste fino: O ajuste fino modifica o arquivo model.pt
do modelo original salvo - se desejar manter os pesos originais deverá copiar o arquivo.
Observação: o BPTT apenas altera a duração da sequência enviada para a GPU, mas não afetará o resultado final.
python -u main.py --epochs 50 --nlayers 3 --emsize 400 --nhid 1840 --alpha 0 --beta 0 --dropoute 0 --dropouth 0.1 --dropouti 0.1 --dropout 0.4 --wdrop 0.2 --wdecay 1.2e-6 --bptt 200 --batch_size 128 --optimizer adam --lr 1e-3 --data data/enwik8 --save ENWIK8.pt --when 25 35
python -u main.py --epochs 500 --nlayers 3 --emsize 200 --nhid 1000 --alpha 0 --beta 0 --dropoute 0 --dropouth 0.25 --dropouti 0.1 --dropout 0.1 --wdrop 0.5 --wdecay 1.2e-6 --bptt 150 --batch_size 128 --optimizer adam --lr 2e-3 --data data/pennchar --save PTBC.pt --when 300 400
python -u main.py --epochs 14 --nlayers 4 --emsize 400 --nhid 2500 --alpha 0 --beta 0 --dropoute 0 --dropouth 0.1 --dropouti 0.1 --dropout 0.1 --wdrop 0 --wdecay 0 --bptt 140 --batch_size 60 --optimizer adam --lr 1e-3 --data data/wikitext-103 --save WT103.12hr.QRNN.pt --when 12 --model QRNN
A instrução abaixo treina um modelo PTB que sem ajuste fino atinge perplexidades de aproximadamente 61.2
/ 58.8
(validação/teste), com ajuste fino atinge perplexidades de aproximadamente 58.8
/ 56.5
e com o aumento contínuo do ponteiro de cache atinge perplexidades de aproximadamente 53.2
/ 52.5
.
python main.py --batch_size 20 --data data/penn --dropouti 0.4 --dropouth 0.25 --seed 141 --epoch 500 --save PTB.pt
python finetune.py --batch_size 20 --data data/penn --dropouti 0.4 --dropouth 0.25 --seed 141 --epoch 500 --save PTB.pt
python pointer.py --data data/penn --save PTB.pt --lambdasm 0.1 --theta 1.0 --window 500 --bptt 5000
A instrução abaixo treina um modelo QRNN que sem ajuste fino atinge perplexidades de aproximadamente 60.6
/ 58.3
(validação/teste), com ajuste fino atinge perplexidades de aproximadamente 59.1
/ 56.7
e com o aumento contínuo do ponteiro de cache atinge perplexidades de aproximadamente 53.4
/ 52.6
.
python -u main.py --model QRNN --batch_size 20 --clip 0.2 --wdrop 0.1 --nhid 1550 --nlayers 4 --emsize 400 --dropouth 0.3 --seed 9001 --dropouti 0.4 --epochs 550 --save PTB.pt
python -u finetune.py --model QRNN --batch_size 20 --clip 0.2 --wdrop 0.1 --nhid 1550 --nlayers 4 --emsize 400 --dropouth 0.3 --seed 404 --dropouti 0.4 --epochs 300 --save PTB.pt
python pointer.py --model QRNN --lambdasm 0.1 --theta 1.0 --window 500 --bptt 5000 --save PTB.pt
A instrução abaixo treina um modelo PTB que sem ajuste fino atinge perplexidades de aproximadamente 68.7
/ 65.6
(validação/teste), com ajuste fino atinge perplexidades de aproximadamente 67.4
/ 64.7
e com o aumento contínuo do ponteiro de cache atinge perplexidades de aproximadamente 52.2
/ 50.6
.
python main.py --epochs 750 --data data/wikitext-2 --save WT2.pt --dropouth 0.2 --seed 1882
python finetune.py --epochs 750 --data data/wikitext-2 --save WT2.pt --dropouth 0.2 --seed 1882
python pointer.py --save WT2.pt --lambdasm 0.1279 --theta 0.662 --window 3785 --bptt 2000 --data data/wikitext-2
A instrução abaixo será um modelo QRNN que sem ajuste fino atinge perplexidades de aproximadamente 69.3
/ 66.8
(validação/teste), com ajuste fino atinge perplexidades de aproximadamente 68.5
/ 65.9
e com o aumento contínuo do ponteiro de cache atinge perplexidades de aproximadamente 53.6
/ 52.1
. É provável que números melhores sejam alcançados, mas os hiperparâmetros não foram extensivamente pesquisados. No entanto, esses hiperparâmetros devem servir como um bom ponto de partida.
python -u main.py --epochs 500 --data data/wikitext-2 --clip 0.25 --dropouti 0.4 --dropouth 0.2 --nhid 1550 --nlayers 4 --seed 4002 --model QRNN --wdrop 0.1 --batch_size 40 --save WT2.pt
python finetune.py --epochs 500 --data data/wikitext-2 --clip 0.25 --dropouti 0.4 --dropouth 0.2 --nhid 1550 --nlayers 4 --seed 4002 --model QRNN --wdrop 0.1 --batch_size 40 --save WT2.pt
python -u pointer.py --save WT2.pt --model QRNN --lambdasm 0.1279 --theta 0.662 --window 3785 --bptt 2000 --data data/wikitext-2
Para obter velocidade em relação ao PTB em nível de caractere e enwik8 ou WikiText-103 em nível de palavra, consulte o artigo relevante.
As velocidades padrão para os modelos durante o treinamento em uma NVIDIA Quadro GP100:
Os modelos QRNN padrão podem ser muito mais rápidos do que o modelo cuDNN LSTM, com as acelerações dependendo do gargalo do RNN. A maior parte do tempo do modelo acima agora é gasto em softmax ou sobrecarga de otimização (consulte a discussão do PyTorch QRNN sobre velocidade).
As velocidades são aproximadamente três vezes mais lentas em um K80. Em um K80 ou outros cartões de memória com menos memória, você pode querer ativar o limite no comprimento máximo da sequência amostrada para evitar erros de falta de memória (OOM), especialmente para WikiText-2.
Se a velocidade for um problema importante, o SGD converge mais rapidamente do que a nossa variante do ASGD desencadeada não monotonicamente, embora alcance uma perplexidade geral pior.
Para obter detalhes completos, consulte o repositório PyTorch QRNN.
Todos os aumentos no LSTM, incluindo nossa variante do DropConnect (Wan et al. 2013) denominada redução de peso, que adiciona dropout recorrente, permitem o uso da implementação cuDNN LSTM da NVIDIA. PyTorch usará automaticamente o backend cuDNN se for executado em CUDA com cuDNN instalado. Isso garante que o modelo seja rápido para treinar, mesmo quando a convergência pode levar centenas de épocas.