🕌

拡散モデルを使った文生成モデルについての紹介

2022/12/18に公開約6,900字

この記事はSansan Advent Calendar 2022の記事です。

はじめに

こんにちは。fujisyo32です。入社してから1年が経過しました。いくつかのコンペに参加したり、国内の学会で発表したり、インターンのメンターを担当したりと色々あった一年でした。さて、今年は拡散モデルを使った画像生成モデルが広く共有されインターネット上で話題になっていました。拡散モデルのベースとなるアイデアはシンプルで、ノイズからスタートして徐々にノイズを除去していくことで画像を生成します。


https://arxiv.org/abs/2006.11239

話題になったのは文章をもとに画像を生成するモデルですが、このアイデアは他の生成モデルでも当然使えるはずです。そこで文生成もできるんじゃないかなと思っていたところ、すでに先行研究が複数あったので紹介します。

拡散モデルは画像などの連続値に適用することを想定されており、スカラー値などの離散値への適用は向いていません。なぜなら意味ベクトルである[0,0,0][0.1,-0.1,0.1]は近い意味を持っていますが、idとしての45は全く異なる意味を持つ可能性があるからです。この問題をどのようにして解決するのかというのが、紹介する手法の肝となっています。

Structured denoising diffusion models in discrete state-spaces

NeurIPS 2021に採録された研究です。この章の画像の出典は https://arxiv.org/abs/2107.03006です。

概要

離散値に対して拡散モデルを適用するためにDiscrete Denoising Diffusion Probabilistic Mode(D3PM)が提案されました。意味ベクトルに対して拡散モデルを適用するのではなく、カテゴリ分布に対して拡散モデルを適用します。そして、ノイズを付与する操作の代わりに独自の操作を導入しています。

工夫

Diffusion models for discrete state space


\text{Cat}(x;p)pが与えられた時のxのカテゴリ分布です。ここでのQ_tというのが時刻tでの操作に該当します。一般的な拡散モデルではノイズ付与に相当する部分です。

Qの具体的な処理について

  • Uniform
    一様分布を加え、一定の確率で他の語彙に変化させる操作です。
  • Absorbing state
    一定の確率でトークンが[MASK]になるようにする操作です。
  • Discretized Gaussian
    通常の拡散モデルと同様にガウシアンノイズを加える操作です。
  • Token embedding distance
    一定の確率で他の語彙に変化させる操作なのですが、類似性が高いトークンに変化しやすくします。

実験と結果

文生成をしている実験だけ紹介します。text8という英語wikipediaのデータセットで言語モデルとしての性能を検証しました。text8はa-zのアルファベットと-の28種類の語彙で構成されているため、提案手法の検証に適していたようです。

absorbing stateが提案手法の中で最もNLL(Negative Log Likelihood)が低いですが、それでもtransformerに比べると劣っています。画像生成タスクでの指標で既存手法を上回っていたものの、文生成の方は性能は低いという結論になっていました。


absorbing stateで生成する過程です。tが大きいほど初期状態に近く、tが小さくなるにつれて[MASK]が減っていくのがわかります。

Analog Bits: Generating Discrete Data using Diffusion Models with Self-Conditioning

この章の画像、疑似コードの出典は https://arxiv.org/abs/2208.04202です。またgithub上でコードが公開されています。 https://github.com/lucidrains/bit-diffusion

概要

下記のイメージがベースとなるアイデアです。「5に対して拡散モデルを適用するのが難しければビット列[0,1,0,1]に変換してから適用すればいいじゃないか」という発想です。

自然言語を分かち書きしさえすれば、あとはトークンをidに変換し、それをビット列に変換すれば画像と同じ要領で扱うことができるようになります。
「私は山田です」→「私 は 山田 です」→[3,4,2,5]→[[0,1,1],[1,0,0],[0,1,0],[1,0,1]]

工夫

工夫として紹介されている2つとも初見で読んだ時はよくわからなくて疑似コードを見て初めてわかったので先に疑似コードを載せます。左が学習時のコードで、右が推論時のコードとなっています。

何をやっているのかというと、学習時は引数xをビット列x_bitsに変換した後、ランダムに決めた時刻tに応じてノイズを加えたx_crptをモデルに入力し、x_bitsを出力できるように学習しています。そして、推論時はx_tに対してsteps回だけノイズ除去を行なってからバイト列をintに変換しています。

Self-Conditioning

これは学習時に行っている工夫です。一般的なやり方は推論時の引数は2つで、f(x_crpt,t)のように推論を行います。一方で、提案手法ではf(x_crpt,f(x_crpt,0,t),t)とf(x_crpt,0,t)の2つのどちらかをそれぞれ50%の確率で学習します。わかりにくいですがやっていることはstackingの亜種で、stacking前段のモデルとstacking後段のモデルを同時に学習してしまうイメージだと思います。上手くいくかはわからないですが、様々のタスクに応用できそうな手法だなと思いました。

Asymmetric Time Intervals

これは推論時に行っている工夫です。一般的なやり方だと推論時はx_{t-1}をf(x_t,t)として計算します。しかし、提案手法ではx_{t-1}をf(x_t,t-td)と計算しています。この工夫によりノイズが減ったと主張しています。tdの値はタスク依存のハイパーパラメータのようです。

実験と結果

画像生成についての実験も行っていましたが文生成の方の実験だけ紹介します。MS-COCOという画像を入力としてキャプションを生成するタスクで検証したようです。


比較対象はAutoregressive Transformerで、劇的に性能が改善したというわけではないものの、一定の改善が見られたようです。

また、前述のAsymmetric Time Intervalsのハイパーパラメータの調整についての実験もあり、かなり大きくスコアに影響することが示されています。

5stepでtime differenceが0.0の場合は下記のような計算になります。
x_0=f(x_4,1.0)、x_1=f(x_2,2.0)、x_2=f(x_3,3.0)、x_3=f(x_4,4.0)、x_4=f(x_5,5.0)
そして、time differenceが8.0の場合は、
x_0=f(x_4,0.0)、x_1=f(x_2,0.0)、x_2=f(x_3,0.0)、x_3=f(x_4,0.0)、x_4=f(x_5,0.0)
と推論されることになります。推論時に適切なtを設定することが最終的な出力に大きく関係しているのは知見だなぁと思いました。

Diffusion-LM Improves Controllable Text Generation

NeurIPS2022に採録された研究です。この章の画像の出典は https://arxiv.org/abs/2205.14217です。また、github上でコードが公開されています。https://github.com/XiangLi1999/Diffusion-LM

概要

単語ベクトルに対して拡散モデルのアイデアを適用するというアイデアです。この際にただ適用するのではなく、各時刻tでclassifierの条件を満たすように学習を行います。ここでのclassifierというのは入力された条件を満たしているかどうか判定する機構です。

工夫

Continuous Diffusion Language Modeling

下記の式に従って学習します。


\hat{\mu}(x_t,x_0)はノイズ加える処理qの事後分布q(x_{t-1}|x_0,x_t)の平均で、\mu_{\theta}(x_{t-1},x_t)はモデルの予測p_{\theta}(x_{t-1}|x_t)の平均です。EMB(w)は単語wを埋め込む処理です。

Reducing Rounding Errors

全ての時刻tx_tからx_0を予測します。
\mathcal{L}_{x_0-simple}^{e2e}(x_0)=\sum_{t=1}^T \mathbb{E}_{x_t}||f_{\theta}(x_t,t)-x_0||^2
f_{\theta}(x_t,t)x_tからx_0を予測する処理です。全ての時刻tx_tからx_0を予測することによって単語のembeddingをうまく学習できるようになるようです。

Controllable Text Generation

制約を満たすように出力することも一緒に学習する必要があります。そこで、p_{\theta}の中身は下記のようになります。
p_{\theta}(x_{t-1}|x_t)=\lambda \log p(x_{t-1}|x_t)+\log p(c|x_{t-1})
p(x_{t-1}|x_t)は言語としての流暢さ、p(c|x_{t-1})は制約を満たすことを意味します。単になんでもいいから生成したいのであれば\lambda=0にすればよく、制約を強く満たしてほしいのであれば\lambdaを大きくするイメージです。

実験と結果

タスク


一般的なタスクと入出力が逆向きのタスクです。

  • Semantic Content
    • fieldとvalueが与えられ、その内容に沿った文を生成
  • Parts-of-speech
    • 品詞の系列が与えられ、それを満たすように文を生成
  • Syntax Tree
    • 構文木が与えられ、それを満たすように文を生成
  • Syntax Spans
    • スパンの成分が与えられ、それを満たすように文を生成
  • Length
    • 単語数が与えられ、それを満たすように文を生成
  • Infilling
    • 前後2文が与えられ、それらをつなぐ文を生成

結果

E2Eというレストランのレビューのデータセットと、RocStoriesという時系列的つながりがある5文が1つの文書になっているデータセットで検証しています。ctrlは入力の制約を満たしている割合、lmは同じドメインでfineutuneしたGPT2のperplexity(流暢さを示す指標)で、低いほど優れています。ctrlは条件をみたしている割合を示しており高いほど優れています。

また、2つの制約を満たすように文生成を学習した場合において、両方のタスクで高い性能を発揮することが報告されていました。

終わりに

最後まで読んでいただきありがとうございました。私が最初に拡散モデルを言語生成に適用する方法として思いついたのは1つ目に紹介した[MASK]の数を少しずつ減らすモデルだったのですが、「やはり少し考えて思いつくことは誰かにやられているのだなぁ」と思いました。画像生成ほどのキャッチーさはないものの従来の自己回帰生成モデルではできないことができるようになっているので来年の動向も楽しみです。

[追記]
この記事を書いた後見つけたのですが、有志がまとめた拡散モデルを使った言語生成モデルの論文リストがあったので紹介しておきます。https://github.com/heejkoo/Awesome-Diffusion-Models#natural-language-generation

Discussion

ログインするとコメントできます