英語帝国を打倒しよう

言語の壁に計算機で挑もう!

LLMについて学び直す3週間

週3日ぐらい取れそうなので、一日1つぐらいでやっていきたい

  1. とりあえず作ってみる→ LLM構築タイムアタック - yasagurenlp’s diary

  2. transformerの並列計算について。何をどう並列化してるんだっけ -> 入力と出力から辿るtransformer(計算量等) - yasagurenlp’s diary

  3. hfのgenerate関数、train関数の引数全部読んでみた

  4. モデルごとにクラスが分かれてるけど、これが何してるか。headとか云々とかも

  5. デコーダーのbackwardの仕組みよく分かってない気がする。とりあえず、decoder-baseモデルをpytorchで書いてみる

  6. LLM計算量。オーダー、理論値、実測値など。空間+時間両方やる

  7. token数、入る入らないとか、拡張できるとか。何?

  8. model parallelを実装してみる重みがどこに載って、どう計算が流れてる?

  9. attentionの可視化って何してる?

  10. 文脈の埋め込みとか。chat-GPTとか前に話したことをどうやって覚えてるんでしたっけ....

LLM構築タイムアタック

目標

自習室みたいなところでバイトを始めた。そこにいれば何しててもいいらしい。→なーんか、今日、暇だな.....人も来ないし.....→LLM作るか

とりあえず、話すようになれば何でもいいかな

タイムライン

14:30 スタート GPU:家のPC(RTX3090) CC-100が良さそうか?よく分からん。日本語で話してほしいな なんか開かないといけないページが多いので、大量の画面の環境構築

15:00 とりあえずGPT-neoXの環境構築。 データの形式とかについてreadmeになんも書いてないところがめんどくせぇ。 prepare_data.pyを読むか→意外に面倒そうやんけ....

こんな感じのこと書いてあったから、とりあえずc4でやってみるか。ただ、デフォルトでやろうとすると多分日本語だけにできないな....全言語ダウンロードするのめんどくさそうだし.... DATA_DOWNLOADERS = { "pass": "pass", "enron": Enron, "pile_subset": PileSubset, "pile": Pile, "github": Github, "arxiv": ArXiv, "europarl": EuroParl, "freelaw": FreeLaw, "nih": NiH, "pubmed": PubMed, "books1": Books1, "books3": Books3, "hackernews": HackerNews, "openwebtext2": OpenWebText2, "stackexchange": StackExchange, "ubuntu_irc": UbuntuIRC, "youtube_subtitles": YoutubeSubtitles, "c4": C4, "c4_openwebtext": C4OpenWebText, "enwik8": Enwik8, }

15:30 eleutherが作るものってなんか秘密結社っぽくてかっこいい 下のenではなくja版のファイルないかなーって思って探すけど、enしかねぇ。英語帝国に従順な秘密結社だった....

class C4(DataDownloader):
    name = "c4"
    urls = [
        f"https://the-eye.eu/eleuther_staging/c4/en/c4-train.{i:05}-of-01024.json.gz"
        for i in range(1024)
    ]

C4をダウンロードしようとした。allenaiというところからjaだけダウンロードできるらしい

github.com

しかし、800GBある。うーん。とりあえず、C100(15G)とかで試してみるか

16:00 通信律速!!!!!!!!!!許せん。家の通信環境も悪いのだが、大学でも8時間ぐらいかかる。 多分、元の方に問題がある。

データについてよく考えてみる GPT-2のデータ数はこんな感じらしい(モデルサイズは1.5B) 50,000 BPE token -> 200,000 文字位 → 1文字3バイトとして、600,000 byte →0.6Gぐらい?ということはGPT-2の再現ならC100でも十分すぎるか

一旦中断

Python自体のバージョンとパッケージのバージョンの依存関係

Pythonのバージョンの依存

これまで理解が曖昧過ぎたので、今日出会ったトラブルと知ったことだけでもまとめる。

トラブル

大学のPCでpip install huggingface_hubしてもあんまりバージョンが新しくならない。(0.5.0にしかならない)が、github等を見ると0.18.0がlatestになっていた。

とりあえずpip install huggingface_hub == 0.18.0をすると、そんなものはないと言われる。

ERROR: Could not find a version that satisfies the requirement huggingface-hub==0.11.0 (from versions: 0.0.1, 0.0.2, 0.0.3rc1, 0.0.3rc2, 0.0.5, 0.0.6, 0.0.7, 0.0.8, 0.0.9, 0.0.10, 0.0.11, 0.0.12, 0.0.13, 0.0.14, 0.0.15, 0.0.16, 0.0.17, 0.0.18, 0.0.19, 0.1.0, 0.1.1, 0.1.2, 0.2.0, 0.2.1, 0.4.0)

PyPIの見方、使い方

基本的にgithubと同じようなことしか書いてなくて情報量がない(少なくともhuggingface_hubは)のだが、左側にpythonとの依存がちゃんと書いてある。 色々見ていくと、大学のPCでデフォルトで入ってたpython3.6までで対応があるのがhuggingface-hub0.4.0までだった

久しぶりにOSから環境を構築して、詰まったこと

ハードウェア

SSDを指すところの上の金属を止めるナットが抜けて、秋葉原にヘキサゴンソケットを買いに行くことになった。名前初めて知った

これはバエ写真....ではなく、抜けたナットを取り外せなくなって困っている写真

ヘキサゴンソケット

OSのブート

nouveauの性能が悪いからなのか、ブートするときに画面が上8割ぐらいしか写っておらず、下側に矢印などでも移動できなかったため、パーティションを指定してのブートができなかった ー>ブートしたいSSD以外を抜いてブートしたらなんとかなった。しかし酷い

Cudaのインストール

11.8が入れたいという欲求があったのだが、まずこれが結構めんどくさい。下の記事と同じような状況になった。公式の通り入れると最新版が入ってしまうと言うやつ。 公式版の最後の行をcuda-11-8とすれば良い。

公式のやつ
5cf21 note.com

Pythonの環境構築

Python3.10がほしかったので、とりあえずデフォルトで入ってた3.8を消して3.10を入れるかーと思っていれたら、driverなど全てが死んでOSのインストールからやり直しになった。 多分driverとかも3.8に依存してるのかな。

文字列比較とDFT

文字列比較とDFT

フーリエ変換についてこれまでほぼ知らなかったのだが、大学の渋谷先生の講義で遂に出会ったので書いておく。講義資料はこちらで、ここからの引用も多い。

 

個人的に気づきだったこと

  • ハミング重みは多項式の積の係数っぽくなる。

  • 逆DFTは関数のN個の値から係数を導く操作だと思う。

 

問題設定

ハミング重みを求めたいとする。

ハミング重みとは、一致している文字の数を表す。

図は渋谷先生の講義資料から拝借

https://www.hgc.jp/~tshibuya/classes/seq2021_2fft.pdf

渋谷先生の配列解析アルゴリズム特論より



ハミング重みと多項式

文字の種類は結構少ないとし、今は「Cの一致数」についてだけ考えることにする。

渋谷先生の配列解析アルゴリズム特論より



一つ目の文字列(ここではAATGTCGCTACGTCGTCCAACGCATTAC->0000010100100100110010100001)と、二つ目の文字列(ここではCTACATG->1001000)を考える。

それぞれに対して、多項式を定義する。

一つ目: AATGTCGCTACGTCGTCCAACGCATTAC:

f(x) = 0 * x^n + 0 * x^{n-1} + ............ 0 * x^1 + 1 = An * x^n + An-1 * x^{n-1} + ......... A1 * x + A0

二つ目:CTACATG

g(x) = 1 * x^m + 0 * x^{m-1} + ............ 0 * x^1 + 0 = Bn * x^n + Bn-1 * x^{n-1} + ......... B1 * x + B0

こう思うと、f(x) * g(x)のx^mの係数についてかんがえると、Am * B0 + Am-1 * B1 ..... + A0 * Bm とかになっていて、なんかハミング重みっぽくなってくる。

ここで、Bを反転してみると、f(x) * g(x)がハミング重みを表しそう(はじっこの方はだめだけど)

ということで、多項式の積f(x) * g(x)が計算できればよい。この多項式の計算で出てくるのがFFT

 

FFTについて

tatyamさんのこの記事を参考にした

一番書き残しておきたいこと:逆DFTは関数のN個の値から係数を導く操作だと思う

DFTと逆DFT

ぐぐると、周波数成分だとか、スペクトルだとか言う話もしばしばでてくるが、こういった三角関数の話は一旦ここでは忘れて多項式の世界を考える。

DFT

数列 A = (A0, A1, .... An) と、f(x) = An * x^{n} + ..... A1 * x^{1} + A0を考える。

今、単位円の根(e^{0*2*pi/N}など)にたいして、f(e^{0*2*pi/N})などを求める。

(お気持ち:これ単体で何か起きることはなさそう。代入して求めるだけなんよね)

逆DFT

ある多項式fをf(x) = CN * x^{N} + ..... C1 * x^{1} + C0として、以下のN+1個の入力-出力について値が分かっているとき(f(e^{0*2*pi/N}), f(e^{1*2*pi/N}), ... f(e^{(N-1)*2*pi/N}))CN,CN-1,.....C0が求まる。

(これは、e^{1*2*pi/N}....の性質がいいからか、楽に求まり、かつ必ず求まる?)

DFTと多項式

A = (A0, A1, .... An) と、B = (B0, B1, .... Bm)があって、f(x) = An * x^{n} + ..... A1 * x^{1} + A0, g(x) = Bn * x^{n} + ..... B1 * x^{1} + B0 とする。

f(x) * g(x) = h(x) とする。

この時、N = n*m -1 として、h(e^{0*2*pi/N}), h(e^{1*2*pi/N}), ... h(e^{(N-1)*2*pi/N})は、f(e^{0*2*pi/N})...,g(e^{0*2*pi/N})....などから簡単に求まる。

そうなると、hについて逆DFTをして、hの係数が求まってしまう。

 

FFT

これはDFTから結構簡単に導けるのでここでは書かない。