Este repositório contém a implementação oficial do artigo um modelo de difusão discreto reparameterizado para geração de texto.
A base de código é implementada com Fairseq. Para instalar as dependências, execute (recomendado em um ambiente virtual) os seguintes comandos:
pip install -r requirements.txt
# install our package of discrete diffusion models
pip install -e discrete_diffusion
# install our fork of fairseq
cd fairseq
python3 setup.py build develop
cd ..Nota O ambiente é testado com Python 3.8.10, Pytorch 1.10.0/1.12.0 e CUDA 11.3. Observe também nosso garfo de Fairseq modifica vários arquivos na base de código original; O uso de versões mais recentes do Fairseq pode levar a conflitos inesperados de dependência.
Implementamos modelos de difusão discretos em uma biblioteca independente discrete_diffusion para uso geral. A biblioteca fornece implementações de vários modelos típicos de difusão discretos, consistindo em
(Vanilla/Reparameterized) multinomial diffusion : processos de difusão que injetam ruído uniform na sequência do token. A implementação da difusão multinomial de baunilha segue de perto a base de código do artigo original;(Vanilla/Reparameterized) absorbing diffusion : processos de difusão onde os tokens dentro da sequência podem ser absorvidos pelo estado masking , conforme descrito no papel D3pm. Esses modelos de difusão compartilham o mesmo conjunto de interfaces, permitindo usos externos. Em particular, eles são definidos como subclasses da classe DiscreteDiffusion , assumindo a seguinte forma:
class DiscreteDiffusion ( nn . Module ):
"""
The parent class for discrete denoising diffusion probabilistic models.
It supports the following methods:
- q_sample()
Sample x_t ~ q(x_t | x_0) to construct noisy Transformer inputs.
- compute_losses()
Compute the loss L_t = KL(q||p) at t-th time step.
- sample_step()
Sample x_t ~ p(x_{t-1} | x_t, x_0) at t-th time step.
"""
def __init__ ( self , num_timesteps ):
super (). __init__ ()
self . num_timesteps = num_timesteps
def q_sample ( self , x_0 , t , ** kwargs ):
"""
Sample from q(x_t | x_0), which is used as the model inputs.
Args:
x_0: token ids with shape [B, N]
t: current time step, tensor with shape [B]
Returns:
return a dict of relevant outputs including x_t.
"""
def compute_losses ( self , inputs , ** kwargs ):
"""
Compute the loss objective KL(q||p) to train our generative process.
Args:
inputs: a dict that contains input types specific to different diffusion processes, containing
- x_t: token ids with shape [B, N]
- t: scalar timesteps, with shape [B]
Returns:
possibly return a dict of relevant outputs, including the loss used for training.
"""
def sample_step ( self , decoder_out , denoising_fn , ** kwargs ):
"""
Given a time step t, start from x_t and sample x_{t-k} from q(x_{t-k} | x_t).
Args:
decoder_out: a namedtuple that contains decoding info, including
- x_t: token ids with shape [B, N]
- t: scalar timesteps
- max_steps: the maximum number of decoding steps
- ...
denoising_fn: a function that takes in x_t and t and returns model logits
kwargs: other arguments that are used to control decoding.
Returns:
return a new decoder_out namedtuple.
""" Um modelo DiscreteDiffusion pode ser instanciado ao configurar o seguinte:
--num-diffusion-timesteps <int> Especifica todo o número de etapas do tempo de difusão (padrão: 50)--diffusion-type <str> Especifica o tipo de modelo de difusão (opções: {absorbing, multinomial, reparam-absorbing, reparam-multinomial} )--noise-scheduler-type <str> Especifica o cronograma de ruído apenas na difusão multinomial de baunilha/reparam (escolhas típicas: {linear, cosine} ; padrão: cosine )q_sample() , incluindo--q-sample-mode <str> especifica a estratégia de amostragem (opções: {default, coupled, multi-step, multi-sample} ; padrão: default ). Fornecemos várias opções para amostragem de default : uma única amostra é desenhada como multi-step : Exemplo de duas etapas de tempo IID multi-sample : Exemplo de duas amostras IID coupled : também conhecido como treinamento condicionado, que é detalhado no Apêndice F do artigo. Isso começa com a amostragem de duas etapas do tempo IID coupled traz melhorias significativas para a difusão multinomial/absorvente de baunilha, mas o ganho não é consistentemente substancial em variantes reparameterizadas.--not-diffusing-special-sym indica se deve incluir símbolos especiais durante o processo de difusão (padrão: false)compute_losses() , incluindo--reweighting-type <str> Especifica o esquema de re-ponderação em nossa família reparameterizada (opções: {linear, reciprocal, none} ; padrão: linear )--label-smoothing <float> Especifica a taxa de suavização de etiquetas (Padrão: 0.1)sample_step() , incluindo--argmax-decoding indica se o uso da decodificação do Argmax para a saída do transformador denoizado --temperature <float> Especifica a temperatura --decoding-strategy <str> Especifica o uso de baunilha ( default ) / reparameterizado ( reparam-<options> ; veja os detalhes) Estratégia de decodificação (escolhas: {default, reparam-<options>} ; default: default )--load-ema-weights indica se deve carregar os pesos do modelo EMA para geração (padrão: false)--iter-decode-max-iter <int> Especifica o número máximo de timesteps para decodificar (Padrão: 10)--iter-decode-with-beam <int> Especifica o tamanho do feixe para decodificar várias seqüências com diferentes comprimentos em paralelo (padrão: 1)--iter-decode-force-max-iter indica que a decodificação iterativa deve executar o número especificado de iterações e não sair. Recomendado para definir este sinalizador como true.Veja aqui uma lista mais abrangente de argumentos.
Ao passar --decoding-strategy default , o esquema de amostragem de baunilha (específico para cada processo de difusão discreto) é usado.
Uma abordagem de decodificação mais avançada pode ser invocada pela aprovação --decoding-strategy reparam-<conditioning-of-v>-<topk_mode>-<schedule> . Essa abordagem é baseada no reparameterismo proposto em nosso artigo e permite procedimentos de decodificação mais eficazes. As opções especificam o algoritmo de decodificação via
uncond <conditioning-of-v> cond uncond <topk_mode> : stochastic<float> ou deterministic ( deterministic padrão): se deve usar a seleção estocástica ou determinística. O valor da flutuação em stochastic<float> especifica o grau de aleatoriedade na seleção estocástica do topo-$ k $;<schedule> : linear ou cosine ( cosine padrão): o cronograma para Consulte a implementação para obter mais detalhes sobre as opções.
Por favor, veja os scripts abaixo para obter detalhes.
Observação
- Observe que todas as tarefas consideradas neste trabalho operam nos dados originais e não adotam a destilação do conhecimento (KD).
Seguimos o pré-processamento padrão em Fairseq/Exemplos para preparar os dados binarizados:
# fetch and preprocess the data to BPE codes
cd examples/translation/
bash prepare-iwslt14.sh
cd ../..
# binarize the data
TEXT=examples/translation/iwslt14.tokenized.de-en
fairseq-preprocess --joined-dictionary --source-lang de --target-lang en
--trainpref $TEXT /train --validpref $TEXT /valid --testpref $TEXT /test
--destdir data-bin/iwslt14.tokenized.de-en
--workers 20Usamos os dados divulgados no Fairseq/Exemplos para preparar o conjunto de dados:
wget http://dl.fbaipublicfiles.com/nat/original_dataset.zip
unzip original_dataset.zip
TEXT=wmt14_ende
fairseq-preprocess --joined-dictionary
--source-lang en --target-lang de
--trainpref $TEXT /train.en-de --validpref $TEXT /valid.en-de --testpref $TEXT /test.en-de
--destdir data-bin/wmt14_ende --thresholdtgt 0 --thresholdsrc 0
--workers 20Para este conjunto de dados, usamos o braco de dados wmt16.tar.gz como pré-processado neste repositório.
tar xzvf wmt16.tar.gz
TEXT=wmt16/en-ro
# move train/ dev/ test/ bpe codes into the $TEXT folder
mv $TEXT /train/corpus.bpe.en $TEXT /train.bpe.en
mv $TEXT /train/corpus.bpe.ro $TEXT /train.bpe.ro
mv $TEXT /dev/dev.bpe.en $TEXT /dev.bpe.en
mv $TEXT /dev/dev.bpe.ro $TEXT /dev.bpe.ro
mv $TEXT /test/test.bpe.en $TEXT /test.bpe.en
mv $TEXT /test/test.bpe.ro $TEXT /test.bpe.ro
# binarize the data
fairseq-preprocess --joined-dictionary
--source-lang en --target-lang ro
--trainpref $TEXT /train.bpe --validpref $TEXT /dev.bpe --testpref $TEXT /test.bpe
--destdir data-bin/wmt16_enro --thresholdtgt 0 --thresholdsrc 0
--workers 20 Entramos pela primeira vez na pasta fairseq e depois executamos os seguintes comandos para treinar os modelos.
# ####### training scripts for IWSLT'14 , WMT'14, and WMT'16
# first cd to fairseq
# we use 1 GPU for IWSLT'14, 4 GPUs for WMT'14 and 2 GPUs for WMT'16 datasets respectively.
CUDA_VISIBLE_DEVICES=0 bash experiments/mt_train.sh -m absorbing -d < iwslt/wmt14/wmt 16> -s default -e True --store-ema --label-smoothing 0.1
CUDA_VISIBLE_DEVICES=1 bash experiments/mt_train.sh -m multinomial -d < iwslt/wmt14/wmt 16> -s default -e True --not-diffusing-special-sym --store-ema --label-smoothing 0.0
CUDA_VISIBLE_DEVICES=2 bash experiments/mt_train.sh -m reparam-absorbing -d < iwslt/wmt14/wmt 16> -s default -e True --q-sample-mode coupled --store-ema --label-smoothing 0.1 --reweighting-type linear
CUDA_VISIBLE_DEVICES=3 bash experiments/mt_train.sh -m reparam-multinomial -d < iwslt/wmt14/wmt 16> -s default -e True --not-diffusing-special-sym --q-sample-mode coupled --store-ema --label-smoothing 0.1 --reweighting-type linearObservação
-s <str>é usado para especificar o nome do experimento.- Poderíamos passar argumentos personalizados que podem ser específicos para o treinamento, anexando -os depois
-e True.
O pipeline de avaliação é tratado por experiments/mt_generate.sh . O script gerará os resultados da tradução e avaliará a pontuação BLEU.
# ########## IWLS'14, WMT'14, and WMT'16 datasets
# we recommend putting each checkpoint into a separate folder
# since the script will put the decoded results into a file under the same folder of each checkpoint.
CUDA_VISIBLE_DEVICES=0 bash experiments/mt_generate.sh -a false -c < checkpoint_path > -d < iwslt/wmt14/wmt 16> Argumentos:
-a : se deve ter uma média de vários pontos de verificação-c : indica a localização do ponto de verificação. Se -a false (não para os pontos de verificação média), passe no caminho do ponto de verificação; Se -a true , passe o diretório que armazena vários pontos de verificação em diferentes etapas de treinamento para a média.-d : o nome do conjunto de dadosTambém fornecemos os pontos de verificação de nossos modelos treinados.
| Conjunto de dados | Modelo | Link do ponto de verificação |
|---|---|---|
| IWSLT'14 | Multinomial | link |
| IWSLT'14 | Absorvente | link |
| IWSLT'14 | Reparam-multinomial | link |
| IWSLT'14 | Reparam-absorvendo | link |
| WMT'14 | Multinomial | link |
| WMT'14 | Absorvente | link |
| WMT'14 | Reparam-multinomial | link |
| WMT'14 | Reparam-absorvendo | link |
| WMT'16 | Multinomial | link |
| WMT'16 | Absorvente | link |
| WMT'16 | Reparam-multinomial | link |
| WMT'16 | Reparam-absorvendo | link |
Seguimos a configuração experimental no Diffuseq para geração de perguntas e parafraseando tarefas.
Os dados brutos dessas duas tarefas podem ser buscados no repositório Diffuseq original. Em seguida, binarizamos os dados através do script fornecido.
# put the raw data in the directory ``diffuseq_data/QG``
# Preprocess the question generation dataset
bash diffusion_mt/scripts/preprocess_diffuseq_datasets.sh QG
# put the raw data in the directory ``diffuseq_data/QQP``
# Preprocess the paraphrasing dataset
bash diffusion_mt/scripts/preprocess_diffuseq_datasets.sh QQP # QQP or QG datasets
# first cd to fairseq
CUDA_VISIBLE_DEVICES=0,1 bash experiments/diffuseq_train.sh -m absorbing -d < qqp/qg > -s default -e True --store-ema --label-smoothing 0.1
CUDA_VISIBLE_DEVICES=2,3 bash experiments/diffuseq_train.sh -m multinomial -d < qqp/qg > -s default -e True --not-diffusing-special-sym --store-ema --label-smoothing 0.0
CUDA_VISIBLE_DEVICES=0,1 bash experiments/diffuseq_train.sh -m reparam-multinomial -d < qqp/qg > -s default -e True --not-diffusing-special-sym --q-sample-mode coupled --store-ema --label-smoothing 0.1 --reweighting-type linear
CUDA_VISIBLE_DEVICES=2,3 bash experiments/diffuseq_train.sh -m reparam-absorbing -d < qqp/qg > -s default -e True --q-sample-mode coupled --store-ema --label-smoothing 0.1 --reweighting-type linear Seguimos de perto os protocolos de geração e avaliação, como no Diffuseq, para garantir uma comparação frente a frente. Todo o pipeline é reimplementado em fairseq/diffusion_mt/scripts/decode_diffuseq.py e fairseq/diffusion_mt/scripts/eval_diffuseq.py respectivamente, para serem compatíveis com FairSeq. Execute os seguintes comandos:
# we recommend putting each checkpoint into a separate folder
# since the script will put the decoded results into a file under the same folder of each checkpoint.
CUDA_VISIBLE_DEVICES=0 bash experiments/diffuseq_generate.sh -a false -b true -c < checkpoint_path > -d < qqp/qg > Argumentos:
-a : se deve ter uma média de vários pontos de verificação-b : se deve usar várias amostras para decodificar MBR-c : indica a localização do ponto de verificação. Se -a false (não para os pontos de verificação média), passe no caminho do ponto de verificação; Se -a true , passe o diretório que armazena vários pontos de verificação em diferentes etapas de treinamento para a média.-d : o nome do conjunto de dadosTambém fornecemos os pontos de verificação de nossos modelos treinados.
| Conjunto de dados | Modelo | Link do ponto de verificação |
|---|---|---|
| QG | Multinomial | link |
| QG | Absorvente | link |
| QG | Reparam-multinomial | link |
| QG | Reparam-absorvendo | link |
| Qqp | Multinomial | link |
| Qqp | Absorvente | link |
| Qqp | Reparam-multinomial | link |
| Qqp | Reparam-absorvendo | link |
@article { zheng2023rdm ,
title = { A Reparameterized Discrete Diffusion Model for Text Generation } ,
author = { Zheng, Lin and Yuan, Jianbo and Yu, Lei and Kong, Lingpeng } ,
journal = { arXiv preprint arXiv:2302.05737 } ,
year = { 2023 }
}