【生成式人工智慧與機器學習導論2025】第 9 講:影像和聲音上的生成策略 — Diffusion/Flow-matching 系列和接龍 (Autoregressive) 這兩條世界線的交會
By Hung-yi Lee
Summary
Topics Covered
- 像素接龍效率太低
- 語音影像用Token壓縮
- MaskGIT擺脫掃描順序
- 連續Token突破離散極限
- Flow Matching結合接龍
Full Transcript
各位同學大家好啊 我們就來上課吧 那今天這堂課要講的是 影像跟聲音上的生成策略 那到目前為止呢 我們課堂主要都集中在語言模型 那這些語言模型可以輸入一段文字 輸出一段文字 我們都知道說 這個語言模型怎麼產生文字呢
都是透過文字接龍 那今天呢 這堂課我們要來講 這一些生成式的人工智慧 它們是怎麼產生圖片 甚至產生影片 它們是怎麼產生聲音 怎麼說一句話 甚至唱一首歌 那麼來看看這些產生影像 產生聲音的技術 跟文字上有什麼樣不一樣的地方
但是呢 在開始講技術之前 我想展示一下 現在這一些生成式人工智慧 在生成影像 生成影片 生成聲音上 到底可以做到什麼樣的地步 但很多這些平台 大家可能也都玩過 但是給還沒有玩過的同學知道一下 現在這一些人工智慧 到底可以做到什麼樣的地步
首先呢 現在很多生成式人工智慧 都可以輸入一段文字 然後按照文字的描述 產生對應的圖片 那做得非常好的一個 就是 NanoBanana 那這是 Google 的模型 那你可以在 Gemini 上呼叫到 NanoBanana 那我就在 Gemini 上呢 要求 NanoBanana
產生 PTT 八卦版 鄉民貼文的截圖 就這樣一個指令而已 它產生出來的輸出 是這個樣子的 所以這個是機器產生出來的輸出 它裡面的文字都是讀得懂 而且都是合理的 一開始它就知道這個看板 是 Gossiping Po 文的人 是 PTT Loser
他的暱稱是魯蛇之王 他抱怨的是 巷口雞腿便當漲到 160 了 然後他就說剛才肚子餓 大雞腿飯發現要 160 元 去年才 130 前年才 100 這漲幅比我的薪水還高 月薪三萬的魯蛇 是不是只能吃土了 然後下面 有一堆人推文 而且這些人的帳號都是有意思的 第一個人是 First Floor
他是第一樓 他就說哥投降 早就破 200 了好嗎 然後一個叫 Salary Slave 薪水奴隸 他說 20 年來經濟最好 Rich Daddy 說窮人整天叫 嫌貴你不要吃啊 為什麼這個人叫做 Egg Lover 我也不知道 這個人叫做 A5566 所以這個 NanoBanana 還創造了一堆
鄉民的暱稱 而且看起來都蠻有道理的 你可能會想說 這個真的是影像嗎 它會不會只是把文字 Po 到貼到一個影像上 那我蠻相信它是直接產生這張圖片的 因為你看右下角 它這邊有一塊小小黑色的東西 還想要模擬說這是在螢幕上面呈現的結果 然後這些文字啊
如果你放大來看 有一些比較複雜的地方 它其實是有一些模糊的 或者是你看這個 160 的 0 你們非常仔細看喔 它 0 中間有一條斜線 但是 100 跟 130 的 0 中間是沒有斜線的 所以我蠻相信它是直接產 這個這是直接產生圖片產生出來的 那看到這邊有人可能會再進一步 引申說 哎呀這個影像生成的模型
厲害到這個地步了嗎 它知道鄉民的 ID 是什麼 也能夠猜測鄉民是什麼 也許它是一個世界模型 是一個 World Model 那這個部分我就比較保留 因為我是在 Gemini 上呼叫這個模型 所以你不知道 當你輸入這個指令的時候 Gemini 有沒有試圖去強化它 Gemini 那個語言模型 有可能 但我們不知道它背後實際上做了什麼 但是有可能
它把我的指令轉化得更複雜一點 它先去猜測說 鄉民在八卦版上應該會講什麼 所以它已經要把 要生成的文字先想好 然後再把更複雜的指令丟給 NanoBanana 所以我們現在沒有辦法確定說 是不是所有的內容 所有的知識都是 NanoBanana 有的 還是有些知識 其實是 Gemini 有的 但是總之這張圖片
是有一個影像生成的模型 所生成出來的 那還有更驚人的例子 現在我給 NanoBanana 呢 一張線性代數期中考的考卷 然後留下一些空白 然後它可以輸入文字 然後告訴它說 給我這份考卷被考試學生完成後的樣子 所以它會根據這張圖片進行修改
它修改完的結果長這樣 我仔細檢查一下它的計算過程 都是對的 它拿到滿分啊 很厲害啊 那這張圖片 是不是文字直接另外 key 上去的呢 我還是蠻相信 它是直接產生這張圖片的 你看這些字 它這個 1 2 3 甚至是沒有對好的 它這個文字 是有點斜的 這個 w
有時候有一個勾勾 有時候沒有一個勾勾 所以我蠻相信它是自動生成的 那至於這個解法 是不是 NanoBanana 自己想的 還是 Gemini 先想好 再告訴 NanoBanana 告訴它要生成什麼樣的文字 那這個我們就不得而知 總之 你現在在 Gemini 上 自動呼叫 NanoBanana 它可以做到這樣子的地步 那現在呢
當然也可以產生語音 讓機器說話 那如果你輸入一段文字 比如說你好 然後機器呢 就把這段文字念出來 那這個是語音合成 但語音合成 這樣子的技術 大家都非常熟悉了 Google 小姐 就是語音合成的一個例子 但現在呢 光是做語音合成 讓機器
產生 Google 小姐的聲音是不夠的 今天呢 這些語音合成的模型 往往除了文字以外 還可以輸入一段語音 那這段語音的作用是什麼呢 這段語音的作用 是為了要控制輸出的聲音 聽起來是什麼樣的感覺 比如說 你跟語音合成系統說 輸入的文字是你好
然後給它一個女生的聲音說 Goodbye 它就會用這個女生的聲音 說你好這兩個字 那這個女生的聲音 甚至不是中文 那你卻可以讓機器模仿這個女生的聲音 說出中文 那這個可以用在什麼樣的地方呢 這個就可以用在 AI 配音 比如說本來是英文的影片
那你可以根據原來英文影片的配音 去產生對應的中文的台詞 那這可以做到什麼樣的結果呢 那這邊就是給大家看一個叫做 IndexTTS2 的模型產生出來的結果 那 IndexTTS2 的團隊呢 就用他們技術幫各式各樣知名的影片片段配音 比如說大家很熟悉的這個
臣妾做不到啊 我們直接從 臣妾做不到阿那段開始 然後等一下你會先聽到那個 中文的原音 再來你會聽到 用IndexTTS這個模型 跟模仿中文的原音 唸出來的英文的台詞 所以他可以做到這樣 好那我們來看另一個例子阿
這邊有這個MYGO的例子阿 來播一下MYGO的例子 是一個名場面 我甚麼都願意做這個名場面 來看一下用中文演繹的結果 這就是 中文配音聽起來就是這個樣子 好 所以你知道今天語音合成可以做到甚麼事情 那除了產生人的聲音之外
現在機器也可以產生音樂 也可以唱歌 那產生音樂一個非常知名的模型呢 就是 Suno Suno 你可以給它歌詞 然後呢它就幫你把歌詞唱出來 它自己作曲 然後自己把歌詞唱出來 不過做歌呢 做產生歌詞呢也是很麻煩的 所以我這邊用 Gemini 來產生歌詞
我就跟 Gemini 說 寫一首歌說明想訓練模型 卻沒有運算資源的痛苦 然後它就產生歌詞 然後再把歌詞丟給 Suno 它就產生一首歌 因為 Gemini 一開始產生歌詞 其實就非常好了 所以我幾乎沒有修改 就直接丟給 Suno 它唱起來是這個樣子的 我現在來播放 這個是純粹由 AI 做歌曲
裡面沒人類什麼事情 他就唱出你的心聲 這個歌聽著聽著就落淚了 那現在當然也可以產生影片 那像 Sora 呢 它不只是你給它一段文字 根據文字產生影片 你還可以給它一張圖片 所以它可以根據一張圖片 一段文字產生影片 而且它產生的影片 都是有聲音的
所以我就嘗試給了它這樣一張圖片 大家在看 YouTube 的時候 是不是常常看到這種廣告啊 然後就叫你要用兩步來解這個遊戲 我想了一下應該是 先把下面這個插銷拔掉 然後呢這個岩漿就會掉到下面的水池裡面 然後再把這個插銷拔掉 然後公主就掉下來 然後錢就掉下來
然後這種廣告通常會先拔掉這一個 然後你就沒有錢了 總之就是這麼樣一個廣告 然後呢我就問 Sora 叫它產生解開這個遊戲的過程 看看它能不能解開這個遊戲 以下是 Sora 直接產生的結果 不知道在做什麼 不知道它在幹嘛 然後再試了一次 第二次呢 它又產生中文的配音 這個謎題只允許兩步
先把中間的插銷拔掉 讓金幣先留下來 替公主墊出一層隔離 等金幣掉滿後 再抽掉最下方的插銷 岩漿會被金幣擋住並流走 不會燙到人 公主安全注入 順便撿到一地黃金 完美 阿這睜眼說瞎話 然後我就想說 那 Sora 能不能夠自動來上課呢 所以我就給它 我們上一次上課的投影片封面 然後告訴它
這是課程的投影片封面 請產生課程 然後告訴它 它知道標題是 通用模型的終身學習 講者是李宏毅 那我們來看看 Sora 產生什麼樣的結果 這是 Sora 直接生成的結果 歡迎來到通用模型的終身學習課程 我是李宏毅 這門課要帶大家認識 當模型不再只針對單一任務 而是像人一樣 一生都在學習時
我們會遇到什麼挑戰 又有什麼新的機會 並嘗試讓模型持續吸收知識 它產生一個假的李宏毅出來 大家知道這個假的人 必須叫做李宏毅 你看它產生了一些文字 這些文字顯然是直接生成的 因為根本看不懂它到底想要寫什麼 但這個是一個影像生成模型 直接產生出來的結果 那我又再試了一次 嗨 大家好 我是李宏毅
這門課要和你一起探索通用模型 如何做到終身學習 這個也是 Sora 直接產生的結果 應該很神奇的是 它一開始出現名字的時候 我的名字下面還出現臺大電機系 我很訝異它到底是怎麼知道的 當然如果是影像模型直接產生出來 那我會覺得有點驚訝 那如果是其實有文字模型的輔助
文字模型剛好做了 RAG 或者從 Memory 裡面讀出說 現在的使用者李宏毅是臺大電機系的教授 那我其實沒有這麼驚訝 這邊這個文字你看 它也是直接生成的 所以會有一些奇怪的錯字 這邊有個 QR Code 我掃了什麼都沒有 就這樣子 所以你知道今天影像生成可以做到什麼樣的地步 那今天要講什麼呢
今天要講的不是 Diffusion Model 那如果你想要知道跟 Diffusion Model 有關的事情的話 那在 2024 年的生成式人工智慧導論 其實花了蠻多時間講了 Diffusion Model 那今天會稍微講一下 今天有一個看起來有取代 Diffusion Model 趨勢的模型 叫做 Flow Matching
那其實在這個影像還有聲音的生成上 除了 Diffusion Model 這條路徑以外 還有另外一個路徑 就是用 Auto Regressive 也就是接龍的方法來進行生成 那所以今天會主要以 Auto Regressive 這個角度來作為主軸 然後講 Auto Regressive 這個角度 如何跟 Flow Matching 還有 Diffusion Model
另外一個研究的路線結合起來 他們如何在 2025 年的時候走在一起 那這可能是今天最前沿的影像跟語音生成的技術 所以今天只會側重在 Auto Regressive 這條研究路線上面 那如果你想多知道一些另外一條路線發生的事情的話
你可以看一下去年生成式 AI 導論課程裡面講的一些內容 好 那我們就開始今天有關技術的部分 那我們從開學的第一堂課就跟大家講說 所謂的生成啊 就是你先知道你要生成的東西的基本單位是什麼
接下來做接龍把這些單位一個一個生成出來就結束了 所以我們要問的是如果我們今天要產生的是聲音 那聲音它可能是音樂 它可能是人說話的聲音 那還有或者是影像 那它們的基本單位到底是什麼 我們來先看一下構成影像的基本單位
但這個部分對很多人來說都是基本常識 大家知道說構成影像的單位其實是像素 然後每一個像素呢又可以分成三個子像素 就是 RGB 三個顏色的子像素 每一個子像素它的數值是 0 到 255 之間 也就是有 256 種可能 那我本來想要做投影片講解這個
那我想說做這一頁投影片實在是太無聊了 能不能直接用 Sora 產生一個教學影片 所以我就說創作一個教學影片 畫一個二次元的人物 並展示這個人物是由像素構成的 每個像素又由 RGB 三個子像素所組成 每個子像素的可能數值範圍是 0 到 255 我們來看看 Sora 能不能直接產生教學影片
這樣就可以取代人類老師的角色 以下是 Sora 直接產生的影片 大家看看你根據它講的內容你學不學得了 用像素畫出角色完成 它看起來很細緻對吧 但它其實是由小方塊堆成的 這就是一個像素 每個像素裡有三個子像素 RGB 他們的數值範圍從 0 到 255
不同的組合就成了不同 它這個講的話都跟畫面沒有對到 而且你看它這個字幕居然是生成的 而且你看這個它字幕都會產生一些奇奇怪怪的字 它字幕居然是直接透過一個影像模型產生出來的 剛才我們都說機器看到李宏毅三個字 會產生一個假的李宏毅老師
但是其實 Sora 是有個人化的功能的 你其實可以給它某一個人的影像 然後告訴它說這個人呢以後就叫做宏毅李 然後接下來你再告訴它說創造一個由宏毅李講解的教學影片 它就可以用宏毅李這個角色來講解教學影片
那就是為什麼現在網絡上充斥的 Altman 在做各式各樣的事情的影片就是這麼來的 其實在我們今天要講解的作業裡面 也有 personalization 的部分 只是我們沒有做影像生成那麼複雜 我們是做的是圖片生成 那大家可以體會一下說這種 personalization 可能是怎麼被做出來的
好,所以剛才呢一樣的敘述、一樣的指令 我改成是有李宏毅講解的教學影片 剛才啊我們看過的那些李宏毅都是假的李宏毅 那線上看聽課程的同學你可能從來不知道我長什麼樣子 那我長得呢跟前面兩段有李宏毅的影片是一點都不像啦 那我們來看一下如果客製化之後 它產生的結果長什麼樣子
先來畫一個二次元角色 用最簡單的線條開局 臉型、頭髮、衣服輪廓都勾出來再加上一點表情 上色後的她長這樣,是一位短髮穿著連帽衫的女孩 可是放大來看你會發現其實是由一塊塊像素拼成的 每一個像素裡面 好雖然最後結尾的時候表情有點奇怪 但是我確實差不多就是長這個樣子 所以如果你無法想像我長什麼樣子的話 我其實真的是長這個樣子的 好那剛才講的是產生圖片
那怎麼產生影片呢 其實影片就是一連串的圖片 只是你在產生圖片的時候 那些像素只要考慮兩個維度 只要考慮寬跟高 那如果是影片的話 影片是由一連串的圖片所構成的 所以你還要考慮第三個維度 也就是時間 那在影片裡面的一連串的圖片 在影片裡面的每一張圖片
有一個專有名詞叫做 Frame 如果是翻成中文的話 通常就翻成幀 好那剛才講的是有關影像的部分 那聲音呢 聲音的基本單位又是什麼呢 我們一樣由 Sora 來跟大家說明 Sora 就用我這個角色來做一個教學影片 它告訴大家說 聲音訊號是由取樣點構成的 遠看是聲音訊號
拉近後可以看到一個一個的取樣點 一秒鐘有多少的取樣點 取決於取樣率 也就是 Sampling Rate 也就是說假設 Sampling Rate 是 16 kHz 意味著一秒鐘有 16000 個取樣點 那每個取樣點有多少種可能的數值呢 這取決於取樣的解析度 也就是 Bit Resolution
那 16 個 Bit 意味著解析度有 65536 種可能的數值 好那我們就播放一下 你聽到的聲音訊號其實是一條連續的波形 拉近來看就會發現 它是由一個一個的取樣點連起來的 一秒鐘有多少取樣點取決於取樣率 像這裡的 16000 Hz 代表一秒鐘有 16000 個取樣點 而每個取樣點可以有多少種不同的數值 這又取決於
這個影片講到一半就結束了 而且它最後還手震 你好好產生影片不行嗎 還學人類手震啊 所以 Sora 要產生教學影片 還是有它的極限 那我這邊試了一下 HeyGen 這是另外一個平台 那 HeyGen 上面如果你要創造影片的話 它其實是用一個 Agent 產生出來的 也就是它不是一個步驟生成的 如果是剛才的 Sora 它是直接根據文字就直接產生影像
那 HeyGen 背後呢 應該是呼叫了某一個語言模型 雖然細節我們並不清楚 它會把它用多個步驟來完成 那背後其實也會 call Sora 有一些需要生成影像的地方 它可能是用 Sora 生成的 但是它是用一個 Agentic 的 Framework 透過多個步驟來產生教學影片的 所以一樣的指令丟給 HeyGen 它產生出來的影片是這個樣子的
好,那我們當然可以把影像跟語音生成 看作是像素或者是取樣點的接龍 那如果你今天訓練一個接龍的模型 它根據你的輸入 你的輸入可能是文字 然後它就產生一堆的像素的話 那這些像素集合起來 它就是一張圖片
那如果今天接龍的模型產生出來的是取樣點 代表聲音訊號的取樣點 把這些取樣點集合起來 它就是聲音訊號 那影像生成我們知道就是像素接龍 那這樣子的概念其實早在寒武紀 也就是 2016 年的時候人類就已經知道了
在寒武紀的時候就有一個模型叫做 Pixel RNN 那你從這個投影片上 Pixel RNN 的圖 就可以看出來說它做的事情 就是把一張圖片裡面的像素 一個一個的生成出來 把我的雷射筆叫出來,等我一下 好,它就是把這個像素 由左到右、由上而下 一個一個的生成出來
那麼我們知道每一個像素 是由三個子像素 RGB 所構成的 那在 Pixel RNN 裡面 要產生一個完整的像素 它就是把 RGB 三個子像素依序產生出來 所以它在這個小圖裡面 還展示了它是怎麼產生 RGB 三個子像素的 那再過了幾個月 有另外一個模型叫做 Pixel CNN 概念是一樣的
就只是把 RNN 換成 CNN 而已 一樣它會把像素一個一個產生出來 那每一次要預測一個子像素的時候 就是從 0 到 255 這個數值裡面 選擇一個數值出來 那因為在 2016 年 在寒武紀的時候 就已經知道用像素接龍了
所以在 2016 年秋季班的機器學習 其實也有展示用像素接龍 產生一張圖片 那個時候用像素接龍的技術 可以產生看起來非常簡單的寶可夢的圖像 然後接下來在過了半年之後 2017 年春季班的機器學習課程 我們就有影像生成的作業 只是那個時候能夠做得非常的有限
那個時候讓大家生二次元的圖片 你生出來就是這樣子 最好就是做到這樣 你也可以輸入文字 但輸入文字只能夠指定眼睛跟頭髮的顏色 你在輸入更多模型是不會理你的 因為訓練資料裡面也沒這樣子的資料 所以用像素接龍可以產生圖片 是在寒武紀就已經知道的事情
那把一張一張圖片產生出來 就可以產生影片 所以其實早在寒武紀的時候 也就是 16 年的時候 有一個模型叫做 Video Pixel Network 它就可以產生一張一張的圖片 它把圖片串起來就是影片 在寒武紀的時候生成出來的影片 長什麼樣子呢 其實後來在一年之後
2017 年的春季班也有課程 是講 Video 的 Generation 那你可以去看一下 2017 年春季班的課程 看看那個時候可以生出來的影片 長什麼樣子 然後接下來 那剛才講的都是有關圖像生成的部分 那有關語音生成的部分呢 早在寒武紀的時候
就已經有一個模型叫做 WaveNet 它做的事情就是 把一段聲音訊號裡面的取樣點 一個一個的預測出來 在這個動畫裡面 橙色的一個一個點 就是聲音中的取樣點 那你從這個動畫的解析裡面 就可以看到說 模型把這些取樣點一個一個產生出來
就可以產生聲音訊號 那 WaveNet 合成出來的聲音訊號 聽起來是什麼樣子的呢 那在有 WaveNet 之前 當然也有很多人嘗試用深度學習的技術 來產生聲音訊號 只是那時候做的沒有非常的好 所以那個時候其實一個比較主流的做法 其實是一個 Concatenate 的做法 也就是說你把一些人的聲音訊號拿來
然後切成一小段一小段的 然後拼起來 就可以產生你要的聲音訊號 那那個時候呢 用 Concatenate 的做法 可以做起來的聲音聽起來像是這樣子的 那這邊用 Traditional 代表傳統的 Concatenate 的方法 聽起來是這樣的 就有點像是 Google 小姐的聲音 那時候用 WaveNet 其實當然以今天的角度來看 合成的其實也不是特別好
但當時用一個一個的取樣點接龍 居然可以做到這個地步 當然今天聽起來是覺得還好啦 但是在十年前 哇這個用取樣點接龍居然可以做到這個地步 這個世界上的人都驚呆了 那當時 WaveNet 呢 也試圖產生了音樂 這個我記得是 Google 的結果啦 他們就把這個
拿一堆鋼琴的聲音去訓練 WaveNet 所以它也可以彈鋼琴 聽起來聲音是這個樣子的 就是這樣啊 彈得好不好不好說啦 聽起來就是鋼琴的聲音就是了 但是像這樣子取樣點 或者是像素接龍的方法 有什麼樣的大問題呢 雖然 WaveNet 可以合出還不錯的聲音 但是在當年就有人發了一個 這樣的 Twitter 文章抱怨
他說這個WaveNet 生成一秒鐘的 Audio 需要花 90 分鐘的時間 實在是太長了 所以因為取樣點這個東西 實在是太細了 用取樣點來當作單位 來產生聲音 實在是非常沒有效率的事情 所以我們接下來要問的是 適合生成的基本單位到底是什麼
也就是語音跟影像的 Token 到底是什麼 這就好像是說 我們講萬物的基本單位都是原子 但是我們在討論人類身體構造的時候 我們通常不會在原子的層級上 來討論人類身體的構造 我們當然說細胞 是構成人體的基本單位 所以語音跟影像也是一樣 拿取樣點或者是像素
來當作語音和影像的基本單位 可能實在是太細了 到底什麼樣的單位 比較適合拿來做語音跟影像的生成呢 那為什麼我們有可能用更大的單位 來作為語音跟影像的 Token 呢 你可以想想看 在聲音訊號裡面 可能 B 這個聲音 如果是同一個人講的 甚至是不同人講的
它看起來的聲音訊號 可能都非常的類似 所以也許這些看起來非常類似的聲音訊號 我們可以直接用一個 Token 來直接表示它 我們可以說 B 這個聲音 以後只要看到這樣子的一段波形 它就是 Token 編號 128 雖然它們有點不一樣 但通通都說是 Token 編號 128 用這種方式來表示語音
你就可以用比較簡潔的方式 來表示語音的訊號 對影像來說可能也是一樣 這邊有一隻貓 牠的左眼跟右眼 可能長得蠻像的 或不同的動物的眼睛 只要是貓科動物的眼睛 可能都長這樣 也許我們就把這樣子的眼睛 直接把它命名為 Token 256 以後這個區塊就叫 Token 256 這個區塊也叫 Token 256
那你可以講說這兩隻眼睛 還是有點不一樣吧 它們的反光感覺是不太一樣的 你怎麼能說它們是一模一樣的東西呢 確實它們不是一模一樣的東西 所以當我們把語音跟影像 表示成 Token 的時候 確實有它的極限 那等一下我們再回來探討這個問題 我們現在先假設說 我們就是把語音跟影像做了 非常大規模的簡化
我們用 Token 來表示語音跟影像 那在講這種 Token 怎麼被自動找出來之前 我們先來講說 假設有了這種 Token 之後 我們怎麼樣來訓練模型 就有了這種 Token 之後 首先有一段聲音訊號 你就會跑過一個步驟叫做 Tokenization 把聲音訊號變成一個 Token 的 Sequence 那 Tokenization 這個詞彙 其實在第一堂課
我們講文字語言模型的時候 就已經說過 那我們之前在看 Hugging Face 的模組的時候 我們在跟大家講這個語言模型示範的時候 那時候就會呼叫一個叫做 Tokenization 的 function 但是這邊語音的 Tokenization 跟文字的 Tokenization 是非常不一樣的 那個文字的 Tokenization 非常的簡單
你就是把一句話分成一個一個 Token 但語音的 Tokenization 我們等一下會看到 你必須要用一個複雜的模型 才能把聲音變成一個一個 Token 那聲音變成 Token 之後呢 你還會有一個叫做 Detokenization 的模組 可以把這一些代表聲音的 Token 轉回聲音訊號 但是因為當我們把聲音訊號 轉成 Token 的時候
中間就失去了一些資訊 本來有點不一樣的聲音訊號 變成一樣的 Token 所以你還原回來之後 就會有失真 所以輸入的聲音訊號 經過 Tokenization 然後再做 Detokenization 其實還原回來 是會有一點不一樣的 我們只是期待說 Tokenization 跟 Detokenization 技術做得夠好 這個失真可以越小越好
所以這個語音跟影像的 Tokenization 跟文字非常不一樣 文字你把文字做 Tokenization 再做 Detokenization 轉回來是一模一樣的東西 但是在聲音和影像上 做完 Tokenization Detokenization 之後 你就沒有辦法還原回 原來一模一樣的聲音訊號 或者是圖片了
圖片你也可以做 Tokenization 把它變成一堆 Token 圖片跟聲音不一樣的地方是 因為聲音是一維的 所以這個 Token 也就是排成一排 但是影像是二維的 所以這些 Token 通常也是二維的 那可以想像每一個 Token 其實就對應到圖片裡面的一個小的區塊
然後可以做 Detokenization 把這個二維的 Token 轉回一張圖片的樣子 當然一樣可能會有失真的問題 那假設我們知道 怎麼把語音跟影像表示成 Token 之後 那語音跟影像 其實跟語言模型是非常像的 它仍然是 Token 的接龍 如果你就要做語音合成
也就讓模型吃一段文字 然後產生聲音的話 那其實就是訓練模型 看到一段文字 然後接下來就去預測 接在這段文字後面的語音 Token 應該長什麼樣子 它把 Token 用接龍的方式 一個一個產生出來之後 做 Detokenization 就會還原回聲音訊號
那你還可以做文字生圖片 文字生圖片就是 給這個模型一段文字 然後它去預測這段文字後面 應該接什麼樣代表圖片的 Token 那它會把 Token 一個一個的產生出來 但是因為圖片本身是二維的 所以這些 Token 雖然它產生出來的時候 是一維的 但是你會把它擺成一個二維的樣子
你會假設這個生成的順序 是由左到右 由上到下 你會把一串 Token 擺成二維的樣子 經過 Detokenization 一樣可以產生一張圖片 這個其實就是語音跟影像生成的原理 所以現在真正的核心 是 Token 怎麼產生 Token 上面 那怎麼產生 Token 呢
如果是語音的話 你找 Token 的方式是這樣的 這些 Token 並不是憑藉人力找出來的 而是自動被學出來的 用某個模型學出來的 怎麼學呢 你要學的是一個 Tokenizer 這個 Tokenizer 其實就是一個類神經網路 它可能是有好多層 CNN 後面接好多層的 Transformer 所構成的
那這個 Tokenizer 吃一段聲音訊號 它的輸出就是一排 Token 那這個輸入的聲音訊號跟 Token 之間有什麼樣的關係呢 輸入的聲音訊號 假設是 16kHz 的話 那通常 Token 呢可能是 50Hz 那當然這邊有很多不同的 Setup 你要做更取樣率更小的 Token
其實也是可以的 那如果你把原來 16kHz 的原始聲音訊號變成 50Hz 的 Token 50Hz 的 Token 就是一秒呢 裡面會有 50 個 Token 那你其實就是把 320 個取樣點變成一個 Token 那一個 Token 其實就是你可以想成就是一個數字
那會有多少個不同的 Token 呢 那就要看你當初在訓練模型的時候 你打算有多少不同的 Token 比如可以說我就是 200 個 Token 我有 200 個不同的 Token 也就是 320 個取樣點 它會被壓縮 我們用從 0 到 199 這 200 個數字的其中一個
來表示這 320 個取樣點 然後接下來你要把它還原 然後 Detokenizer 就吃這個 Token sequence 然後想辦法還原聲音訊號 我們在訓練的時候 通常就是 Tokenizer 跟 Detokenizer 一起訓練 我們就一起訓練 Tokenizer 跟 Detokenizer 希望輸入跟最後還原的聲音訊號越接近越好
你就是找一個 Tokenizer 跟 Detokenizer 你的 Loss 就是輸入跟輸出之間的差距 要讓輸入跟輸出越接近越好 但至於什麼叫做接近 什麼叫做像 什麼叫做聲音上的像 那等一下我們會再有幾頁投影片 來探討這個問題 我們現在先假設 我們就是有辦法計算 兩段聲音之間的相似度 好 那這個呢 其實就是 Autoencoder 的概念
那這個是我們在機器學習 2021 的課程 有講過的 那說你還不知道 Autoencoder 是什麼的話 你可以先看一下 機器學習 2021 的課程 但是我們這邊所訓練的 Autoencoder 是一個比較特別的 Autoencoder 因為你會發現說 中間這個 Tokenizer 輸出的 是離散的東西 是 Token 是 Discrete 的東西 那這需要用一個特殊的技術
叫做 VQ-VAE 來訓練 那這邊我們就不細講 它的訓練方式 那我把原始的論文留在這邊 給大家參考 那其實在語音上呢 這個產生 Token 的方式啊 有一個語音蠻常用的方式 叫做 Residual Vector Quantization 縮寫呢 是 RVQ 那它的想法是這樣 也許只用一組 Token
沒辦法好好的表示語音 因為語音非常的複雜 那如果一組 Token 不夠的話 那也許我們可以多用幾組 所以會有很多個 Tokenizer 第一個 Tokenizer 先產生第一組 Token 那第一組 Token 沒辦法完整表示聲音訊號 就假設你 Token 數目 只有 200 個的話 嗯 320 個取樣點 只用
0 到 199 200 個數字來表示 感覺太勉強了 那再加第二個 Tokenizer 第二個 Tokenizer 呢 去想辦法把第一個 Tokenizer 沒有辦法表示的地方 用另外一組 Token 來表示 然後以此類推 你可以有多個 Tokenizer 比如說你可以 train 個 8 個 Tokenizer 或者可以 train 個 32 個 Tokenizer
然後把每一組 Token 呢 一起丟到 Detokenizer 然後還原聲音訊號 這些 Tokenizer 跟 Detokenizer 是一起做訓練的 那有很多模型 比如說 SoundStream 啊 EnCodec 啊 或者是 Mimi 啊 都用類似的方法來產生 Token 那在我們這堂課的第十個作業呢 會有更多跟語音相關的東西
那到時候在作業裡面 你會玩一下 Mimi 這個 Token 那你會更有概念說 Mimi 的每一組 Token 學到了什麼東西 那這個多組 Token 啊 可以看成像是 進位的概念 什麼意思呢 就是第一組 Token 假設有 200 個可能 第二組 Token 假設也有 200 個可能
那他們總和起來的可能性多少呢 並不是 200 加 200 他們合起來的可能性 其實是 200 的平方 當一段聲音訊號 我用兩組 Token 每組 200 個 Token 來表示的時候 這一段聲音訊號 其實等於有 200 的平方的表示方式 就好像是進位一樣 在進位的時候
這個阿拉伯數字只有 0 到 9 只有 10 個可能 但是透過把這個阿拉伯數字 擺在個位數 十位數 百位數 千位數 你可以創造出無窮無盡的數字 那這邊有多個 Tokenizer 的概念 其實也是非常類似的 你可以想像成這是個位數 這是十位數 所以合起來
有 200 的平方的可能的 Token 語音的 Token 其實有非常多不同的變形 這不是我們在這堂課能夠講的 如果大家有興趣的話 可以看一下這篇有關聲音 Token 的 Overview Paper 我其實也是作者之一 接下來我們來講影像的 Token 影像的 Token 怎麼找呢 一樣你有一個 Tokenizer
唯一跟聲音不一樣的地方 只是影像的 Token 是二維的 所以這個 Tokenizer 產生出來的是二維的 Token 那這個二維的 Token 裡面 每一個 Token 其實就是對應到影像裡面的一小塊 比如說在 OpenAI 的 DALL-E 這個模型裡面
每一個 Token 對應到 8x8 這樣子的小範圍 那在 DALL-E 裡面它用的 Token 數目非常多 它有 8192 個 Token 所以可以想像說影像裡面 8x8 的範圍 它用 8192 個不同的 Token 來描述這個 8x8 的範圍
它就把 8x8 的範圍壓縮成只有 8192 個可能性 然後你會有一個 Detokenizer 把這些 Token 還原回原來的影像 訓練的時候一樣你是希望輸入跟輸出越接近越好 你會訓練你的 Tokenizer 跟 Detokenizer 希望輸入跟輸出越接近越好 訓練完你就知道怎麼把影像變成 Token 怎麼把 Token 還原回影像
那用這樣子的方法找出 Token 之後 再去訓練一個接龍的模型 那個接龍模型其實就跟原來的語言模型其實沒什麼不同 只是 Token 的定義變了而已 真的可以做出很好的影像生成模型嗎 其實是可以的 那這邊引用一篇去年年中的論文 那這是那個論文裡面展示的圖 當然現在你看到這種圖你可能也不會特別訝異啦
不過在當時這個也是不錯的生成的結果 那在那篇 Paper 的標題裡面 它就說 Auto-Regressive Model 就是接龍的模型 Beats Diffusion 其實從這個 Title 可以看出來說 在當時 Diffusion Model 應該是比較主流的方法 所以這篇文章才會特別強調說 它用 Auto-Regressive 的 Model 其實是可以做得比 Diffusion Model 更好的 那其實早在這篇文章之前 就有蠻多文章用 Auto-Regressive Model
超越 Diffusion 的模型 那我之所以特別引用這篇文章是因為 這篇文章還強調了一個點 它是 Llama for Scalable Image Generation 它說前人的文章 都還是對 Auto-Regressive 的模型 針對影像做了一些客製化 做了一些客製化的調整 那等一下我們會講這個調整是什麼 它說它這邊沒做任何客製化的調整 它的模型單純就是 Llama 的架構
Train 下去就沒有然後了 就結束了 就產生了一個影像生成的模型 可以比當時的 Diffusion 還要做得更好 好 那怎麼做這個影片的 Token 呢 那影片就是一串圖片 你把它丟進 Tokenizer 裡面 它也會產生 Token 只是影像的 Token 它是排成三維的樣子
所以它有寬 有高 而且還有時間 那通常在做影像 Token 的時候 每一個 Token 不只是代表 這個一個圖片裡面的一個小區域 它還會代表一個時間的範圍 所以說現在這一個 Token 它不只是代表一個 2x2 的範圍 它還代表一段時間 比如說代表兩個 Frame 所以兩個 Frame 合起來會產生 Token
兩個 Frame 合起來會產生 Token 所以 Token 的這個長度 是比原來輸入的影像的長度 還要更短的 然後接下來那個 Detokenizer 就根據這些 Token 再還原原來的影片 那其他都是一樣的 就是讓輸入輸出越接近越好等等 串下去 然後就結束了 你就可以找出影像的 Token 有了影像的 Token 之後 你只要訓練一個 Transformer
把影像的 Token 一個一個生出來 就可以產生影片了 這樣真的可行嗎 在 2021 年的時候 這個也是遠古時代 就已經有人嘗試過了 有人訓練了一個 VideoGPT 它的方法就是我剛才講的 先找出影像的 Token 那個時候叫做 Discrete 那個時候 Token 這個字眼還不流行 那時候叫 Discrete
然後讓 Transformer 把這些 Token 一個一個產生出來 就結束了 那 VideoGPT 可以產生什麼樣的影片呢 它產生出來的影片大概是這樣子的 就播放一下他們 Demo Web Page 上的影片 就這樣 沒了 再播一次 就這樣子 我知道說以今天的角度來看 你當然覺得說 蛤 就給我看這個嗎 當然在 2021 年 在遠古時代
這已經是非常厲害的東西了 那後來呢 再過了兩年 那那個時候影像生成 就能夠做得更成功了 有一篇文章叫做 Language Model Beats Diffusion 那從它的標題也可以看到說 它想要彰顯的就是 過去主流的方法是 Diffusion Model 那它可以用 Language Model 做出比 Diffusion 更好的結果 那怎麼做到呢 對它來說一個關鍵的技術是
Tokenizer is key to visual generation 他們有更好的找 Token 的方式 那至於他們怎麼樣更好的找出 Token 那這個就大家再詳細閱讀原始的論文 那有了比較好的 Token 之後 再來生影片 可以生出更好的 更清晰的 更流暢的影片 那現在這些影片生成 看起來都非常的驚人 到底用了多少的訓練資料呢
那我們其實不知道 Sora 用了多少的訓練資料 但有一個 Project 叫做 OpenSora 那他們是試圖去復現 Sora 的結果 那根據他們的論文呢 他們說他們用了 30M 其實這比我想像的少 用了 3000 萬部影片 來訓練他們的模型 但今天啊 你要找影片其實不是難題
它這邊就列了很多影片的 Corpus 告訴你說 其實有這麼這麼多影片的 Corpus 那它用的那些影片都是 開源的影片 Corpus 就這些影片是公開的 你可以找到 這個不是什麼秘密的資料 他們花比較多力氣的 反而是在於 Filtering 他們把這些公開的影片 做一下 Filtering 那看到這個圖呢 我們在講語言模型訓練的時候 也看過非常類似的圖
總之需要做非常大量的 Filtering 選出品質比較好的影片 才能夠訓練比較好的 文字生影片的模型 好那影片的 Token 呢 還有一個值得多提的是 影片的 影像的 Token 一定要用 2D 的方式來排列嗎 在我們想像中 影像本身是 2D 的 所以表示影像的 Token 應該也是 2D 的 每一個 Token
表示影像裡面的一個小區域 但是一定要這樣嗎 這會不會不是特別有效的表示方式 我們能不能夠說 一張圖片 就用 32 個 Token 來表示 這個 32 個 Token 沒有固定對應的區域 這 32 個 Token 也許代表的是 影像裡面有什麼樣的物件
比如說也許有個 Token 代表 影像四邊都是綠色的草 某個 Token 代表中間有條狗 用這種方式 其實可以更有效的 來表示一張圖片 所以有一篇論文就說 An image is worth 32 Token for reconstruction and generation 從它標題就知道它想做什麼 它說一張圖片 我們說一張圖片值千言萬語
那它值幾個 Token 呢 值 32 個 Token 那這邊論文就告訴你說 其實你用剛才那個方法 可以把一張圖片 壓成 32 個 Token 來表示它 它做法是這樣 你有個 Tokenizer 這個 Tokenizer 其實是一個 Transformer 這個 Transformer 讀一張圖片做為輸入 然後它就產生一排 Token 那你會先指定好產生 Token 的數目
比如說就產生 32 個 Token 這 32 個 Token 每一個 Token 到底對應到影像的哪邊 不知道 這個是機器自己學出來的 然後再把這 32 個 Token 丟給 Detokenizer 它也是一個 Transformer 讓它還原原來的圖片 訓練的時候一樣 讓輸入跟輸出越接近越好 就結束了
那這 32 個 Token 能好好的表示一張圖片嗎 從文獻上看起來是可以的 這是從原始論文裡面截出來的圖 最下面這個是原圖 那原圖每張圖片有 65536 個 Pixel 那這 65536 個 Pixel 你其實可以用這個 256 個 Token 16x16 個 Token
來還不錯的來表示這一些影像 所以這些圖片是 把這一個原始圖片表示成 256 個 Token 也就是 16x16 個 Token 這邊的 Token 是 2D 的樣子 然後再還原回來 但是如果你仔細看的話 你會發現說 用 256 個 2D 的 Token 排成二維形狀的 Token 來表示圖片 看起來還是有一些資訊的損失的
比如說這個鳳梨的葉子 感覺是有一點點模糊的 你還是可以看出一點點的差異 不過乍看之下 你會覺得中間這一排圖跟下面這一排圖 其實沒什麼差別 那最上面呢 是用一排 32 個 Token 來表示的 那你會發現它其實比較清晰 但用 32 個 Token 來表示一張圖片 其實有一個小小的問題是 有時候那個圖片會被改變
因為想現在每一個 Token 它已經不是對應到一個固定的區域了 它對應的東西比較像是語意 告訴你說這個圖片裡面 有什麼樣的東西 所以如果你仔細看 下面原圖有水花 這裡就沒有水花 然後這個熊的臉的角度 跟這個熊的臉的角度 其實有點不一樣 這隻熊它臉有一點轉向螢幕
這個熊完全是在看左邊 或者是你發現這一隻水母 跟這隻水母 它們的形狀是不太一樣的 所以 Token 裡面可能只表示說 在圖片的右邊要畫一隻水母 但它沒有完全的描述 這個水母長什麼樣子 所以它圖片還是有一點改變的 但是總之這是告訴我們說 你其實可以用更少的 Token
來描述一張圖片 好 那接下來我們來講 什麼叫做像 就是找 Token 的一個核心 就是要量輸入跟輸出 這個 Tokenizer 之前 跟 Detokenizer 之後 你一張圖片 或者是一段聲音訊號 它還原前還原後 到底有多麼的相像 那等一下的討論 我都是用語音作為例子
但是影像上可以用 完全一模一樣的套路 好 什麼叫做像呢 基本上有三種方向的像 第一個像叫做表面上的像 也就是我們回歸到 物件的最基本的單位 在最基本的單位上算它的相似度 如果是聲音訊號的話 那它就是一排取樣點 然後我們就計算
兩堆取樣點之間的相似度 我們就計算兩堆取樣點之間的相似度 計算它們之間的差距 把它們的差距全部平均起來 就是我們的 Loss 就是我們要去 Minimize 的東西 這個東西叫做 Regression 的 Loss 這是表面上的像
那表面上的像有一個非常巨大的問題 如果我們今天把這一些取樣點 全部往右平移一個點 然後最前面補一個 0 那一個取樣點 哇 這個一秒鐘 如果是 16kHz 的 Sampling Rate 一秒鐘 16000 個取樣點 所以你只把取樣點向右平移一個位置 這個人類是根本聽不出差異的
但是如果你去計算 Regression Loss 的話 兩段原來一模一樣的聲音訊號 其實會有天差地遠的差別 所以這個表面上的像 會跟人感知的像有非常大的差距 所以第二種像就是感知上的像 也就是人類聽起來像不像 但我們沒辦法真的找人來聽兩段聲音 告訴你像不像你在訓練的時候 不能這麼做
所以今天採用的方法 是用某一個模型來代替人類 比如說用一個語者辨識的模型 或者是情緒辨識的模型來代替人類 就假設說 我一個很好的情緒辨識的模型 給一段聲音訊號 它可以告訴我是什麼樣的情緒 那產生出來的情緒 人也認為是對的 人認證它是對的 所以這是一個好的
可以模擬人類情緒辨識能力的模型 然後你再把這個模型的某一個 Hidden Representation 某一個 Layer 的 Representation 拿出來算它的相似度 那這個叫做感知上的像 那這個模型給它兩段聲音訊號 從它的 Hidden Representation 抽兩個像量出來 計算它們之間的距離 這個叫做 Perceptual 的 Loss
那還有第三種像叫做 模型難以分辨的像 什麼是模型難以分辨的像呢 你就把原來的聲音訊號 通過 Tokenizer Detokenizer 以後 得到還原的聲音訊號 能有一堆原來的聲音訊號 有一堆還原回來的聲音訊號 然後你去訓練一個模型叫做 Discriminator 這個 Discriminator 做的事 就是分辨一段聲音訊號 它是真正的聲音訊號
還是還原回來的聲音訊號 那如果這個 Discriminator 沒辦法分辨 就代表說 原來的聲音訊號 跟還原的聲音訊號非常像 代表今天還原的非常的好 那代表說這個 Tokenizer 跟 Detokenizer 它們是做得非常的好的 那如果這個 Discriminator 它可以輕易的分辨 兩者之間的差異 那這樣反而是壞的情形
因為就代表說 最後還原出來的聲音訊號 跟原來的聲音訊號 看起來有非常明顯的不同 所以 Discriminator 可以輕易看出 它們兩者之間的差異 那透過 Discriminator Train 好壞 來判斷說我們的 Tokenizer 跟 Detokenizer 做得好不好 這個叫做 Adversarial 的 Loss 那其實呢
這個 Tokenizer 跟 Detokenizer 因為它們是會不斷訓練的 所以它們會訓練得越來越像 它們甚至可以拿 Discriminator 來當作它的目標 它們會拿 Adversarial 的 Loss 當作它的目標來進行訓練 會希望可以讓 Adversarial Loss 越小越好 所以這個 Tokenizer 跟 Detokenizer 可能經過訓練之後
它們產生出來的訊號 會跟原來的聲音訊號 更加相像 但是 Discriminator 呢 也會跟著訓練 就你訓練完 Tokenizer Detokenizer 之後 Discriminator 會拿新生成的結果 也來 Update 參數 也跟著做訓練 那 Discriminator 會越來越嚴苛 那這種訓練一下 Tokenizer Detokenizer 再去訓練一下 Discriminator
這個往復往復這樣的行為 其實就跟一個叫做 Generative Adversarial Network (GAN) 的模型做的事情是一樣的 那如果你想要知道 更多有關 GAN 的事情的話 那我們這堂課時間有限 那我們這學期 其實就沒有講到太多 跟 GAN 有關的事情 如果你想要知道的話 可以再參見機器學習 2021 的內容 好 總之我們現在講了三種像
雖然我們是拿語音做例子 但它其實完全可以套用到 影像上面 就是有表面上的像 感知上的像 跟模型難以分辨的像 那你可以問說 要用哪一種比較好 那這個就是小孩子才問的問題 大人就是全都要 所以今天你其實會把三種不同的像 加起來 然後希望有一個模型 儘量做到三種像都很像
好 那這個是有關 Tokenization 的部分 之前在講文字接龍的時候 我們都假設說接龍就是由前往後 由左向右 但是對於影像 我們一定要由左向右由前往後嗎 那到目前為止 講到影像接龍的時候 影像的 Token 接龍的時候
我們剛才也都是預設說 接龍就是由左向右由上到下 這個接龍的模型 產生一排的影像的 Token 之後 這些 Token 會被擺成由左到右 由上到下的樣子 這種順序叫做 Raster Order 但是影像的接龍 一定要是 Raster Order 嗎 想想看我們人類在畫圖的時候
你其實通常也不會由左向右 由上而下 一個一個 Pixel 的畫出來 人在畫圖的時候 你可能是先畫圖片裡面 你覺得最重要的東西 如果你要畫一隻狗 狗的頭如果在左邊的話 那你就先從左邊開始畫 狗的頭在右邊的話 你就是先從右邊開始畫 所以人在畫圖的時候 也不是按照 Raster Order 在畫的
那我們為什麼讓機器生圖的時候 要按照 Raster Order 來生圖呢 有沒有更好的生成的方法 或甚至我們能不能讓機器自己決定 生成的順序呢 這種方法是有的 有一個方法叫做 MaskGIT 它是 Masked Generative Image Transformer 的縮寫 那這個 MaskGIT 的做法是這樣子的 在訓練的時候
我們先講怎麼做訓練 然後再講怎麼做 Inference 在訓練的時候 它是這樣教模型的 它教模型說訓練資料裡面有 一段文字、一隻奔跑的狗跟對應的圖片 那這個圖片呢 我們把它描述成一串 Token 那這一串 Token 可能本來是二維的 反正就把它拉直 不管它在二維圖片裡面的順序 就會變成一排 Token
然後把這排 Token 呢 其中一些 Token Mask 掉 那哪些要被 Mask 掉呢 就是隨機 Mask 掉 那所謂 Mask 的意思其實可能就是 把這個 Token 換成一個特殊的 Token 你可能保留一個編號 比如說編號 0 代表特殊的 Token 那模型呢 要把這個特殊的 Token 還原回來 那你接下來做的事情
就把這段文字丟給一個 Transformer 把這個裡面有一些 Mask 掉的 Token 的這個 Token Sequence 丟給 Transformer 那 Transformer 訓練的目標 就是把這些被 Mask 的 Token 還原回來 它去猜出這個被蓋起來的位置 原來應該放個籃球 這個位置原來是一個氣球 這兩個位置原來是蘋果
這個是 MaskGIT 訓練的時候的方法 那在訓練的時候呢 這個 Masking 是隨機的 那要 Mask 多少也是隨機的 所以有時候可能在這九個 Token 裡面 會 Mask 掉四個 但有時候可能會 Mask 很多 全部都被 Mask 掉 模型要想辦法只從這段文字
猜出這九個 Token 到底是什麼 那有時候可能 Mask 的非常少 幾乎整張圖片都看得到 只有一小部分被 Mask 起來 那可能對模型來說 這是一個比較容易的任務 這個是訓練的時候 訓練的時候你就是教模型 看到 Mask 如何還原原來的 Token 那測試的時候呢 這個模型訓練好之後 做 Inference 的時候
你做的事情是這個樣子的 有人輸入一段文字 然後你產生一堆 Mask 的 Token 那因為你已經知道圖片的大小 我們通常在產生圖片的時候 你會先設好圖片的大小 所以要有幾個 Mask 的 Token 你是已經事先知道的 所以這樣子的方法 它比較適合用在 已知生成的東西大小的任務上面 那如果你要拿它來生成語音
拿它來生成音樂 因為一段文字進去 要生成多長的對應的聲音 其實有時候並不是一個固定的數值 那你就需要用額外的方法來處理 那在影像上 這個方法用起來是非常的自然的 因為通常圖片的大小 是已經預設知道的 那把這一排 Mask 跟這段文字 丟到我們剛才訓練好的 Transformer 它的工作就是去猜說
被 Mask 起來的地方該是什麼 它就把 Mask 的地方 想辦法還原回來 然後產生這些還原回來的 Token 之後 再把這些 Token 丟到 Detokenizer 希望就可以產生圖片 但是如果你只是這樣做 把給它一堆 Mask 讓它產生一堆 Token 你還原出來的圖片 產生出來的圖片 通常都是非常糟糕的結果
這張圖片是原始論文裡面的例子 它想生一隻紅鶴 但是你看到模型生出來 不知道是什麼奇形怪狀的東西 這黃色東西好像是嘴巴 感覺這邊模型想要放個頭 這邊也想放個頭 這邊也想放個頭 好多地方它都想畫一個紅鶴的頭 全部集合在一起 就是一個奇怪的混合的生物 為什麼會這樣呢 因為這一些 Token
全部都是同時產生的 它們在輸出的時候 彼此沒有協調一下 大家都想畫自己想畫的 大家都針對它對於一隻紅鶴 在圖片的某一個位置要畫什麼 各自做了理解 所以可能在某一個地方 在左上角這個 Token 想要畫一個頭 在中間這個 Token 也想畫個頭 大家看到紅鶴都想要畫一個頭
把頭畫在圖片裡面各個地方 畫出來就是錯誤的結果 所以怎麼辦呢 你需要把一些生成的圖出來的 Token 再蓋回去 那事實上在這個 MaskGIT 實際的操作裡面 通常會把多數的 Token 都蓋回去 只保留少數的 Token 比如說在這個例子裡面 我們假設只保留前三個 Token
只保留三個 Token 其他人都蓋回去 那怎麼決定誰要被保留下來 誰要被蓋回去呢 這邊你可以根據 每一個 Token 產生出來的時候 模型給它的分數來決定 因為產生每一個 Token 跟產生文字的 Token 產生影像的 Token 跟產生文字的 Token 其實一樣的 在每一個位置 其實模型真正產生的是一個機率分布
它會給每一個可能的 Token 一個分數 然後我們再看分數最高的是哪一個 Token 當作是最終的輸出 所以就算這些 Token 都是分數最高的 Token 它們彼此之間還是有分數差距的 我們看每一個 Token 它的分數是多少 可以決定 模型在這個位置產生這個 Token 的時候
它有多確定多想要在這個位置產生 Token 所以假設我們已經知道了每一個 Token 它在這個機率分布裡面的分數 但是要注意一下 這邊並不是同個機率分布裡面的 不同的 Token 的分數 而是每一個位置都有個機率分布 那這些 Token 都已經是 它們那個班級裡面的第一名 只是雖然都是第一名
可能還是有程度的差異 所以每一個第一名再取出來 做一下比較 取出所有第一名裡面的前三名 其他人通通都蓋回去 重新做生成 那你可能會想說 這樣就是最好的方法嗎 取這個分數最高的有道理嗎 在實作上這是一個蠻能運作的方法 那我們實驗室有同學
也做過一些 MaskGIT 相關的研究 實作經驗是 其實把誰保留下來 把誰蓋回去不重要 重點就是 只有一些人可以被留下來 其他人蓋回去 就算這個過程 就誰留下來是隨機的 你就隨機取 K 個 Token 保留下來 其他都蓋回去 結果其實做起來也是差不多的 總之關鍵就是
只有少量的 Token 可以被保留下來 所以可以想成這一步呢 就是 Auto-Regressive 的其中一步 只是一般 Auto-Regressive 一次只能產生一個 Token 現在一次可以產生 K 個 Token 那在這個例子裡面 是一次產生三個 Token 好所以這張圖片還沒被畫完 只畫了三個 Token 接下來呢 把只有三個 Token 的這個 Sequence 多數都是 Mask 的這個 Sequence
再丟進同一個模型 再把 Mask 的地方展回來 那因為有一些地方已經畫起來了 比如說左上角已經畫了一個頭了 因為它已經畫了頭 所以其他人就不可以再畫頭了 我已經知道 輸入已經把頭畫好了 其他人就算沒有互相之間沒有溝通 大家也都知道輸入已經有頭 所以就不會把頭畫出來 所以擺這個位置想要畫一個頭
但它被蓋起來再重新生一次的時候 因為頭已經被畫了 所以它就畫別的東西 可能就畫一個身體 那希望反覆這個步驟 每次只產生 K 個 Token 就好像做 Auto-Regressive 做接龍每次接 三個 Token 只接 K 個 Token 出來 然後最後可以產生完整的圖片 但是跟一般的接龍不一樣的地方是 因為每一次被蓋起來的東西
被保留下來的東西都是不一樣的 所以順序是不固定的 每一張圖片生成的時候 會先產生哪些地方 再產生哪些地方是不固定的 可以說是模型自己決定的 那這個方法 在實作上運作的是蠻好的 那這張投影片裡面的例子 是來自於 MaskGIT 的原始論文 它先說 如果是一般的 Auto-Regressive 的方法
生圖片是這個樣子的 你有 你總共有 256 個 Token 你總共有 16 x 16 個 Token 那你每次就產生一個 Token 每次產生一個 Token 進行 256 次以後 你就可以把整張圖片生出來 所以可以看到說 它要產生一隻紅鶴 這個紅鶴就是從左上角開始生 慢慢的產生完整的紅鶴
那如果用它們的方法呢 它們的方法這個 MaskGIT 每次就是產生一把 Token 每次就產生一把 Token 所以一開始所有 Token 都是被蓋住的 然後接下來 在第一步產生一些 Token 在第二步再產生一些 Token 在第三步再產生一些 Token 但每次實際上是產生全部的 Token 多數蓋回去 所以這邊這個投影片上面 深色代表被保留下來
沒被蓋回去的 Token 所以它就用這個步驟 這些 Token 彼此之間 這個 Token 生成的順序 可能沒有什麼特定的順序 是根據這個圖片的特性來產生的 那最後也一樣可以產生完整的紅鶴 而且需要的步數是比較少的 因為你每次保留 Token 如果大於 1 的話 那你需要的步數 就可以比 Auto-Regressive 的方法 比單純由左而右由上到下接龍的方法
還要更有效 用更少的步數就可以產生圖片 那至於這兩個方法誰比較強 等一下我們在講其他東西的時候 會正好看到一個比較的結果 好那其實這個 Auto-Regressive 可以有好幾層 Auto-Regressive 什麼意思呢 我們在畫圖片的時候 不只不會由左到右而上到下 我們甚至不會一次畫完
完整圖片的所有的細節 你可能是先畫個草稿 再打個底色 然後再把細節畫出來 那我們能不能在生圖片的時候 也做一模一樣的事情呢 比如說我們想要輸入一隻奔跑的狗 輸出是一個 1024 x 1024 高解析度的圖片 但我們沒有必要一步驟 就產生高解析度的圖片
可以先讓接龍模型產生 64 x 64 的圖片 當然這個過程 還是需要做某種程度的接龍 不管你是用一般的 Auto-Regressive 還是 MaskGIT MaskGIT 今天很多人都說 它算是一種 Auto-Regressive 的方法 因為它也是一次產生幾個 Token 不管是什麼樣的接龍的方法 你就先產生比較小的圖 那根據比較小的圖 再用另外一個接龍的模型 把它放大變成 256 x 256 的圖
加上比較多的細節 再用另外一個模型 把 256 x 256 的圖變成 1024 x 1024 的圖 加上更多的細節 那現在生成的時候就有兩個方向 生圖的時候用的是 Token 的 Prediction 你每次都要產生一些 Token 但是從小圖到大圖 你可以看作是 另外一個層次的 Prediction 它是 Next Scale 的 Prediction
所以今天在生圖片的時候 你可以有兩個不同方向 不同角度的 Auto-Regression 兩種不同角度的接龍 從小圖到大圖 也可以看作是另外一種接龍 那像有一個 Paper 叫作 Muse 那這個是 23 年上古時代的文章 它其實就是 MaskGIT 的延伸 它就是 MaskGIT 加上分兩個步驟
來生成圖片 所以它作法是 先有一個比較小的 Transformer 那這個比較小的 Transformer 它的目標就是根據輸入的文字 生成 256 x 256 的圖片 但這個生成的過程是用 MaskGIT 就是每次只 Predict 幾個 Token 出來 其他蓋回去 每次只產生幾個其他蓋回去的方法 產生 256 x 256 圖之後
再根據這個 256 x 256 的圖 擴展成 512 x 512 的圖 那產生 512 x 512 的圖的過程 一樣是 MaskGIT 也就是產生 Token 蓋回去 產生 Token 蓋回去這樣子的方法 那以下是這個 Muse 這篇 Paper 裡面的一個範例 它就告訴你說 在產生 256 x 256 的圖的時候 那你看一步一步
有一隻貓在下圍棋的圖 在下西洋棋的圖慢慢的產生出來 那產生這個小圖之後 再根據小圖去產生大圖 這樣就可以產生高清的大圖 那這種方法還有一個變形叫做 VAR Visual Auto-Regressive Modeling 剛才我們在講 Next Scale 的 Prediction 的時候 好像每一個 Scale 用的都是不同的模型
從小圖生中圖中圖生大圖 用的都是不同的模型 但你其實可以把小圖生中圖中圖生大圖 這一系列的過程 通通用同一個模型來做 這個就是 Visual Auto-Regressive Modeling 的核心的想法 這個 VAR 這個想法就是說 小圖生到大圖 全部也都是用同一個模型 End to End 的訓練出來
所以就是訓練出一個模型 它每一張小圖都是 Auto-Regressive 的生圖 然後小圖再根據小圖生大圖 它有兩層的 Auto-Regressive 但通通是用同一個模型 同一組參數來完成的 那在影像上也可以做非常類似的事情 比如說 NanoBanana Video 就是用類似的方法 它要產生比較高品質的 Video
但是先從低品質的 Video 升起 先產生 Frame 數比較少 比較模糊的圖片 比較模糊的 Video 再從模糊的 Video 逐漸產生清晰的 Video 那因為 NanoBanana Video 倒是 2024 年的時候講過的東西 我們這邊就不再細講 好 那我們剛才已經講了說 在圖片上有一些特殊的生成方法 不一定要用由左到右
而上到下的生成方式 好 那到目前為止 我們都還是用 Token 做為生成的單位 接下來我們就要看 Token 的極限 那 Token 一開始 讓人類更容易的可以做圖片的生成 但是隨著人類對於圖片生成的要求越來越高 人們開始覺得 Token 限制了生成的品質
因為我剛才一直說 Token 就是把圖片做某種程度的壓縮 所以用 Token 來還原圖片的時候 你就是會有一些失真 Token 無法完全表示影像 它竟然無法完全表示影像 當把 Token Detokenize 回來的時候 你生成的影像的品質就會不夠好 而這個品質不夠好 跟接龍模型沒有關係 這個是 Token 的鍋 不是接龍模型的鍋
所以接龍模型你弄再大的模型 用再多的資料最終都沒有用 你的 Upper Bound 可能會被 Token 所限制住 那真的會被 Token 所限制住嗎 這邊就引用一篇去年 10 月的論文 告訴你說確實 Token 有它的極限 而這群作者就拿當時一個比較好的 Tokenizer 他們把一張圖片丟給 Tokenizer
這個 Tokenizer 是把 16 x 16 的範圍 用 8192 個不同的 Token 來進行表示 然後他把一張圖片丟給 Tokenizer 還原回來看看還原後的圖片長什麼樣子 這是丟進去的圖是蒙娜麗莎的畫像 還原回來變成這個樣子 像這樣等級的圖片 如果在一兩年前你其實也可以接受
因為那時候機器生圖很差 但今天你可能很難接受 機器產生這樣子等級的圖片 蒙娜麗莎有點臉歪嘴斜 還增加了一些額外的皺紋 看起來表情怪怪的 總之現在人類已經不能接受 產生這種等級的圖片 所以需要更好的做法 有什麼樣更好的做法呢 Token 限制了我們的模型 描述一張圖片的能力
我們需要更有表述力的 Token 那這種 Token 就是 Continuous 的 Token 所以 Continuous Token 的意思是說 我們現在不再用離散的數字 來表示一個 Token 現在一個 Token 可以是一個向量 向量的每一個維度 都可以是一個 Real Number 我們可以用 16 維的一個向量 來表示一個 Token
那這種用向量來表示一個 Token 就叫做 Continuous Token 那其實很多時候有人甚至現在 會把 Continuous Token 的 Continuous 直接省略掉 所以你讀很多近期的文獻 當他說他用 Token 的時候 其實往往指的已經不是 Discrete 的 Token 而是 Continuous 的 Token 所以當我們用 Continuous Token 的時候 每一個向量 它可以表示的東西
就比原來的 Discrete 的 用整數來表示的東西 多的多非常多了 所以如果你有一個 Continuous 的 Token 那你輸入一個蒙娜麗莎的圖 再還原回來之後 它就可以還原幾乎一樣的圖 所以我們應該要用 Continuous 的 Token 那在這篇論文裡面 它確實也比較了一下
Discrete Token 跟 Continuous Token 的差異 在這個投影片上面 這個藍色跟綠色 藍色跟綠色代表是 Discrete 的 Token 紅色跟黃色代表的是 Continuous Token 橫軸是指接龍模型的大小 越往右代表你的接龍模型越大
這邊是用參數當作單位 縱軸是一個叫 FID 的東西 我們這邊就不細講 FID 是什麼 它代表的是圖片生存的品質 這是一種 perceptual 的 loss 總之這個數值越小 代表你的圖片生存是越好的 那這邊也可以看到說 如果你是用這個虛線的 也就是 Discrete 的 Token 的話
你會達到一個上限 你會在某個時候 你的接龍模型就算是越來越大 你圖片生存的品質也不會再更好 因為它的極限就被 Token 所限制住 那如果你是用 Continuous 的 Token 那隨著模型變大 你的結果是可以越來越好的 那在這一篇配合裡面 他們也順便比較了
這個 Raster Order 跟 Random Order Raster Order 就是由左到右由上到下 Random Order 其實就是剛才的 MaskGIT 那比較這兩種方法 到底哪一種比較好呢 在這個實驗裡面 看起來是 Random Order 比較好 那 Random Order 最後可以產生 黃色的這一條線 所以最終 Random Order 可以給我們最好的結果
那 Raster Order 只能給我們次加的結果 但是其實不是所有的實驗都這樣 它有做一些別的實驗 有時候也有可能 Raster Order 比較好 但總之這個實驗是告訴我們說 Raster Order 跟 Random Order 它們是差不多的 就算是模型今天生成的時候 是用混亂的順序生成的 也可以生成不錯的圖片
好 那我們剛才說我們要用 Continuous 的 Token 那我們顯然就需要訓練一個接龍的模型 使用 Continuous 的 Token 做接龍 那你想說這是個問題嗎 那就是訓練一個模型用 Continuous 的 Token 做接龍囉 那怎麼做呢 好 這個是我們訓練資料裡面一張圖片 這是它對應的文字 把圖片變成 Continuous 的 Token 排成一直線
這個就是我們要生成的目標 我們用 z_hat 來代表要生成的目標 那我們就是告訴接龍的模型說 看到這段文字作為輸入 接下來你要輸出什麼呢 你要輸出的目標就是 z1_hat 這一個向量 每一個 Continuous 的 Token 都是一個向量 所以接龍模型要學會看到這段文字 要儘量輸出跟 z1_hat 越接近越好
那它的輸出跟 z1_hat 之間的距離 我們用 L1 來表示 同樣的道理 如果已經輸入文字 然後給了 z1_hat 這個 Continuous 的 Token 那接龍模型要產生 z2_hat 這個 Token 接龍模型的輸出 要跟 z2_hat 這一個向量越接近越好 我們會計算它的距離當做一個 Loss 把每一筆訓練資料 Loss 全部加起來
是我們要最小化的目標 這個聽起來都是非常 Typical 的方法 但真正難的點來了 真正難的點是 怎麼計算這兩者之間的距離 一個非常直覺的想法 就跟我們之前在前幾堂課裡面 用來計算距離的方式一樣 跟 Regression 的時候用來計算距離的方式一樣 就選 Mean Square Error
也就是計算 z1 跟 z1_hat 之間的 Norm 來當作 Loss z2 跟 z2_hat 之間的 Norm 來當作 Loss 這聽起來非常的直覺 Norm 越小就代表兩個向量的距離越近 那我們就是希望訓練一個接龍的模型 它輸出的向量跟正確答案越近越好 這聽起來沒什麼問題 聽起來非常直覺 但真正的問題就出在這個
聽起來非常直覺的想法上 這個非常直覺的想法 會有什麼樣的問題呢 假設你今天的訓練資料裡面 有兩段類似甚至一樣的描述 都是一隻奔跑的狗 但你知道一張圖片勝過千言萬語 同樣是一隻在奔跑的狗 它對你的圖片可能有千千萬萬的可能 這是在草地上奔跑的狗 這是在城市裡奔跑的狗
它們都是一隻在奔跑的狗 當你今天用接龍模型在訓練的時候 如果你現在的 Batch 裡面 Sample 到這筆資料 那你就告訴接龍模型說 看到輸入一隻在奔跑的狗 那你輸出要跟正確答案 就這個綠色的向量越接近越好 那如果你 Batch Sample 到這筆資料 那你就告訴模型說 看到一隻在奔跑的狗作為輸入
那你的輸出要跟你的正確答案 粉紅色的向量越接近越好 所以你有時候告訴模型 要跟綠色的向量越接近越好 有時候告訴模型要跟紅色的向量越接近越好 不要忘了輸入是一模一樣的 而我們的接龍模型就是個 Neural Network 所以一樣的輸入 它的輸出就是一樣的東西 一樣的東西它根本沒有辦法同時
又跟綠色接近又跟紅色接近 假設綠色跟紅色的向量是很不一樣的話 所以模型最終學到什麼 它就學到說 我希望讓我輸出的結果 既跟綠色接近也跟紅色接近 我要 minimize 跟綠色跟紅色的距離的 MSE 那它得到的結果就是兩者的平均 就是綠色跟紅色的混合
那它如果輸出綠色的向量是對的 輸出紅色的也是對的 但輸出混合的結果就是錯的 本來輸出綠色的你可以畫一隻狗 輸出紅色的可以畫另外一隻狗 輸出綠色跟紅色混合的 你可能就畫一個雙頭狗 那畫出來的東西就是錯誤的東西 所以看起來用 MSE 是有問題的 看起來接龍模型不適用在這個場合上
那講到這邊可能想說 接龍模型不適用在這個場合上嗎 那之前訓練文字模型的時候 做語言模型的時候 怎麼沒考慮到這個問題呢 語言模型應該也有一樣的問題 同樣的未完成的句子 後面可以接很多不同可能 「李宏毅是」這個未完成句子後面 可以接演員也可以接教授 有很多不同的接法
你在訓練的時候有時候會教模型說 看到「李宏毅是」那後面要接「演」 要跟「演」機率是 1 其他 Token 機率是 0 的這樣的機率分布 越接近越好 那如果看到「李宏毅是」 有時候你又教它應該要輸出「教」 應該要跟「教」機率是 1 其他詞彙機率是 0 的狀況越接近越好 那這樣會不會有問題呢
這樣訓練出來的結果是什麼呢 在這個例子裡面 假設有時候你告訴模型 它輸出要是「演」 假設有時候告訴模型輸出要是「教」 它最後產生的機率分布就是 「演」輸出的機率是 0.5 「教」輸出的機率是 0.5 這個是可以讓兩者的 Cross Entropy 的和最小的一個輸出的方式
那輸出這種混合的結果 會不會有問題呢 神奇的是 正好因為我們用的是 Discrete Token 所以這個混合的結果是沒有問題的 為什麼混合的結果是沒有問題的呢 我們今天語言模型的輸出 我們說它的輸出代表每一個 Token 的分數 然後我們得到每一個 Token 的分數以後
接下來你會做取樣 你會去擲一個骰子 根據這個機率分布 決定說「李宏毅是」後面要接「演」 還是要接「教」 它可以決定要接哪一個字 它只會產生某一個 Token 產生「演」也是對的 產生「教」也是對的 它每次只會產生某一個特定的 Token 而不會產生兩個 Token 綜合起來的結果
所以當我們的輸出是 Discrete 跟我們輸出是 Continuous 的時候 狀況是不一樣的 Discrete 直接套用文字接龍的方法 Train 下去沒有問題 但 Continuous 直接套用接龍的方法 Train 下去 當你用 MSE 當作 Loss 的時候 其實是有問題的 那既然問題出在用 MSE 當作 Loss 那感覺我們需要重新定義我們的 Loss 我們要重新定義
我們在輸出 Continuous Token 的時候 我們要用的 Loss 是什麼 這就進入了另外一個研究的世界線 我們剛才講說生成除了用文字接龍的方法以外 有另外一個世界線 有另外一個系列的生成的方法 比如說 VAE 比如說 GAN 比如說 Diffusion 比如說 Flow Model 因為時間有限的關係
今天不會詳細說明這些方法 但是今天會詳細說明這些方法的精神 告訴你另外一個世界線發生了什麼樣的事情 另外一個世界線 最想要處理的問題是 這個世界並沒有標準答案 所以真正的生成問題是這個樣子的 當你告訴一個生成模型 給它一個輸入
叫它去預測下一步要產生什麼的時候 其實並沒有真正正確的答案 真實的答案 標準的答案其實是一個機率分布 在這個機率分布裡面 只要機率高的都是對的 所以一個生成模型 它真正應該要輸出的應該是一個機率分布
然後它輸出機率分布以後 我們再從機率分布去做取樣 來決定要產生什麼 那我們在機率分布上取樣 Sample 到不同的東西 我們最終產生的就是不同的東西 那有趣的是 當我們要生成的是 Discrete Token 比如說文字的時候 這個問題很直覺的就被解決了 因為當我們生成是 Discrete Token 的時候
我們說我們讓模型真正輸出的是一排數字 不要忘了這些模型都是類神經網路 類神經網路真正能輸出的是什麼 它真正能輸出的就是一排數字 但是我們把這排數字 解釋成是每一個 Token 的分數 我們可以說我們讓生成模型 給每一個 Token 一個分數
這個分數代表了一個機率分布 我們再從這個機率分布去做取樣 去做 Sample 就可以給我們一個 Token 所以當我們生成目標是 Discrete Token 的時候 你不會去想說 世界上有多個不同答案的這種事情 因為這個問題很自然的就被解決了 但當我們生成的是一個 Continuous 的東西的時候
這個問題就浮現出來了 假設我們現在要生成的是 Continuous 的向量 那這個世界上正確的答案 給你一個輸入接下來應該要產生的向量 不只一種可能 它是一個機率分布 我們這邊畫一個綠色的 像是阿米巴原蟲的東西 當作一個機率的分布 你可以想像在這個綠色的範圍內
代表這個正確答案出現的機率是比較高的 那這個綠色範圍內的每一個點 都是一個向量 對一個生成模型來說 它充其量能夠生成的東西就是一排數字 所以它能夠生成的就只能是一個向量 它沒辦法生成一個向量的機率分布 所以它沒有辦法生成一個向量的機率分布 所以根本沒有辦法讓生成模型輸出的東西
去跟這個機率分布越接近越好 因為它們本質上就是不一樣的東西 那怎麼解決這個問題呢 這邊就有不同的思路 一個比較早期的思路是 讓生成模型生出來的東西 不是最終的結果 而是讓它生成出來的東西
被解讀成是某種機率分布裡面的參數 什麼叫某種機率分布裡面的參數呢 比如說拿 Multivariate 的 Normal Distribution 為例 一個 Multivariate 的 Normal Distribution 它的參數是什麼 它的參數就是控制它的 Mean 的一個向量 叫做 Mu
控制它的 Covariance 的一個矩陣叫做 Sigma 知道 Mu 知道 Sigma 你就知道這一個 Normal Distribution 它長的是什麼樣子 所以我們讓生成模型生成出來的東西 是 Mu 跟 Sigma 它生成的東西不是一個向量 而是控制一組向量的參數 那假設我們現在的目標的分布
裡面的向量都是 10 維 那這個 Mu 就是 10 維 那這個 Sigma 就是 10 乘 10 維 也就是 100 維 所以你就要求生成模型 生成出一個 110 維的東西 前 10 維就是一個 Normal Distribution 的 Mean 後面 100 維就是一個 Normal Distribution 的 Covariance Matrix 有了這兩個東西 你就定義了一個 Normal Distribution
這個 Mu 告訴我們 Normal Distribution 的中心在哪裡 這個 Sigma 告訴我們 Normal Distribution 的形狀 長什麼樣子 我們訓練的目標 就是要訓練這個生成模型裡面的參數 讓它生成的 Mu 跟 Sigma 產生這個 Normal Distribution 以後 要跟我們真實的答案 要跟我們正確的答案越接近越好
那你這邊有一個顯而易見的問題就是 這個 Normal Distribution 怎麼弄 都是橢圓形的 不管這個 Mu 跟 Sigma 長什麼樣子 都是橢圓形的 你不管怎麼去扭曲這個 產生什麼樣數值的 Mu 跟 Sigma 你都弄不出這個 阿米巴原蟲的形狀 所以如果我們今天是把生成模型 當作是控制某一個機率分布的參數的話
因為我們能夠控制的那些 機率分布都是一些很簡單的機率分布 我們沒辦法真的讓生成模型 產生非常複雜的機率分布 讓它可以跟正確答案非常的類似 尤其假設正確答案 它是真實的資料 它是非常複雜的分布 如果我們只是用產生參數的方法 去控制某一些已知的機率分布的話 我們是沒有辦法
真的跟正確答案非常類似的 所以怎麼辦呢 所以這邊就有了一系列的想法 這一系列的想法 通常會被統稱為 Generative Model 也就是生成模型 雖然 Autoregressive Model 看起來也是一個生成模型 但通常講 Generative Model 的時候 指的是另外一個系列的模型 比如說 VAE、GAN、Diffusion、Flow 雖然這些方法
它們的式子長得看起來非常的不一樣 如果自己有讀文獻的話 往往你就是看得一頭霧水 但它們背後要做的事情 是一模一樣的 它們背後要做的事情是什麼呢 它們背後要做的事情是這個樣子的 我們要讓生成模型 可以生出一個機率分布 怎麼做 生成模型就是一個類神經網路 我們輸入的時候 給它一個 Normal Distribution 什麼叫輸入的時候
給它一個 Normal Distribution 呢 從一個已知的 其實這邊是不是 Normal Distribution 一點都不重要 它就是一個簡單的 你可以從這個 Distribution 去做 Sample 的 Distribution 我們這邊假設它是 Normal Distribution 我們從這個 Normal Distribution 裡面 去做一個 Sample Sample 出一個點 把這個點丟進生成模型裡面
經過一個很複雜的類神經網路的轉換 它會變成另外一個向量 輸入一個向量 然後變變變變成另外一個向量 然後呢 從這個 Normal Distribution 再 Sample 一個向量 通過生成模型又得到另外一個向量 反覆這個步驟 我們可以從 Normal Distribution 裡面 Sample 大量的點 然後從生成式模型輸出大量的點 這些點集合起來
它是一個機率分布 它等於是在近似一個機率分布 而我們希望這個近似跟正確答案 越接近越好 這個生成模型的目標 它就是希望產生一個機率分布 跟正確答案越接近越好 那在等一下的討論裡面 我們會把正確答案當作 Target Distribution 輸入的 Normal Distribution 叫做 Source Distribution 它真的沒有必要一定是 Normal 的
雖然一般文件上都是 Normal 的 但是它沒有必要一定是 Normal 的 而你在文件上看到的 VAE、GAN、Diffusion、Flow-based Model 你覺得它們看起來很不一樣 其實它們要解決的問題 是同一個問題 好 至於它們怎麼解決這些問題呢 在過去的歷史上 每一個模型都曾經紅極一時 那在機器學習的課程裡面 我們也都詳細的討論過它
在 2016 年的機器學習 我們講了 VAE 在 2018 年我們用快十堂課 講 GAN 一個 GAN 的大集合 在 2019 年我們講了 Normalizing Flow 那在 2023 年 我們也用了好幾個小時的時間 詳細的講了 Diffusion Model 如果你有興趣的話 再去看看過去的錄影 非常的長 這個主語合起來 直接當作另外一門課
不適合在今天這個場合跟大家分享 那但是呢 有一個過去沒有講過的方法 叫做 Flow Matching Flow Matching 這個方法 現在非常常被使用 比如說 Stable Diffusion 它第三代的模型 是用 Flow Matching 所以它名字裡面有 Diffusion 但它居然不是 Diffusion Model 它是一個 Flow Matching 的 Model 但其實 Flow Matching 跟 Diffusion 其實非常的像
你甚至可以說是一體兩面 那至於怎麼個一體兩面法 這個留給大家再自己研究 Meta 出了一個叫做 Movie Gen 的模型 可以生成影像 它用的也是 Flow Matching 或者是 Stable Diffusion 的一個競爭 非常強的競爭對手叫 Flux 它用的也是 Diffusion Model 它用的也是 Flow Matching 的 Model Flux 的 F 指的就是 Flow Matching 的 Model 所以你會發現
很多新的模型 用的都是 Flow Matching 的 Model 所以我們有值得來稍微的講一下 Flow Matching 的 Model 指的是什麼 但是要講清楚 Flow Matching 的 Model 其實也不適合在今天這一堂課講 如果大家有興趣的話 可以參加一堂 NTU 的課 裡面就是告訴你 什麼是 Flow Matching 的 Model 所以是用一個學期的時間 來講 Flow Matching 跟 Diffusion Model
還有它們之間的關聯性 那在這一堂課呢 我們剩下的時間也不多 所以不能夠用這種方式 來跟你講 Flow Matching Model 所以等一下我會做的事情就是 直接告訴你 Flow Matching Model 是怎麼運作的 然後我們會有一些範例程式告訴你說 這個看似簡單的運作方式 還真的搞得起來 太神奇了這樣子 好我們現在看 Flow Matching Model 是怎麼運作的
Flow Matching Model 的運作原理是這樣 我們要把一個 Source Distribution 通過一些手段 變成一個 Target Distribution 在 Flow Matching Model 裡面 你第一件要決定的事情是 從這邊變到這邊要幾步 這是一個 Hyperparameter 你要自己決定 它就好像是 Network 有幾層一樣 它是一個你自己決定的東西 比如說我們這邊就決定
我要用四步從左邊走到右邊 好怎麼走 從左邊這個 Source Distribution 先隨便 Sample 一個向量 我們叫它 X0 然後把這個 X0 呢 丟進一個 Flow Matching Model 在 Flow Matching Model 裡面 你一個 Flow Matching Model 它就是一個類神經網路 這個類神經網路 這個 Flow Matching Model
就吃 X0 這個向量當作輸入 除了 X0 這個向量當作輸入以外 它會吃一個額外的 Scalar 一個數值 這個數值代表 我們現在的旅程走了多少 現在旅程還沒有開始 所以輸入是 0 輸入這兩個東西以後 它會輸出另外一個向量 我們這邊用 V0 來表示
它輸出的向量就是告訴 X0 說 你現在要往哪裡走 現在輸出 V0 就是告訴 X0 說 你要往 V0 的方向 走 V0 的四分之一 也就是你要走 0.25 V0 之所以是四分之一 是因為要分四步走 所以每次都只走四分之一 如果你這邊選十步 就十分之一 選一千步就是一千分之一
所以現在就從 X0 往這個方向走了 0.25 V0 到了新的地方 新的地方 我們就叫它 X0.25 代表我們的旅程 已經進行了 0.25 進行了四分之一 再把這個 X0.25 丟給 Flow Match Model 給它一個數字叫 0.25 它告訴你說 在這個位置 如果你的旅程進展到 四分之一的時候
那你就要走 V0.25 這個方向 所以就往 V0.25 這個方向 走 V0.25 X0.25 然後我們就到了 V0.5 這個步驟就反覆一直下去 到 V0.5 以後 問 Flow Match Model 到 X0.5 的時候 問 Flow Match Model 說 到 X0.5 那現在我們旅程進展了一半
那我接下來要怎麼走呢 它說你走 V0.5 這個方向 所以就再往 V0.5 這個方向走 0.25 然後接下來走到 X0.75 這個位置 再反覆一樣的過程 問 Flow Match Model 說 我在這裡 然後旅程進展了四分之三 接下來怎麼走 它告訴你說 往 V0.75 的方向走 你就往 V0.75 的方向走 0.25
然後你就到了一個新的位置 叫做 X1 如果你反覆做這個步驟 你從左邊的 Source Distribution 做一個 Sample 然後就是靠著這個 Flow Match Model 的指引 靠著它當作一個嚮導 告訴你每一步要怎麼走 然後你反覆這個步驟 把左邊的點 移到右邊 它就會從這個圈圈 Normal Distribution 變成你的 Target Distribution
這個阿米巴原蟲的形狀 而這個 Flow Match Model 那如果你更認真地講的話 它就是定義了一個 Vector Field 這個 Vector Field 告訴我們說 在這個空間中 每一個位置 每一個時間 接下來應該要怎麼移動 那再來的問題就是 這個 Vector Field 從哪裡來呢 怎麼訓練出這個 Vector Field 呢
真正難的是怎麼訓練這個 Vector Field 那在講怎麼訓練這個 Vector Field 之前 我再補充一下 你可能會想說 剛才不是說我們只用一個 Neural Network 就從 Source Distribution 變成 Target Distribution 嗎 那 Flow Matching 感覺是不只用了一個 Neural Network 不只用了一次 Neural Network 但你其實可以把 Flow Matching 裡面 整個過程
用到的 Flow Matching Model 全部串在一起 看成是一個很深的 Network 就輸入是 X0 輸入到 Flow Matching Model 裡面 給它一個 Scalar 這個東西有點像是 Bias 它跟輸入是沒關係的 輸出 V0 V0 要乘以 0.25 再加上 X0 這個東西就是 Residual Connection 記不記得我們在第六講的時候講過 Residual Connection 前面的東西會被拉到後面來
把它加起來 再輸給同樣一個 Flow Matching Model 所以它有點像 RNN 同樣的參數在每一個時間點被反覆使用 再給它 0.25 這個 Bias 然後再輸出 V0.25 再乘 0.25 再加 Residual Connection 就一路繼續下去 所以你可以把 Flow Matching Model 好多個 Flow Matching Model 你有幾步就是串幾個 Flow Matching Model 合起來
想成是一個非常巨大的 Network 這個巨大的 Network 過去其實有人想要 End to End 的 Train 它 過去之所以 Flow-based 這種方法做不太起來 就是因為過去一開始的思路是 想要 End to End 的去訓練這個東西 搞不起來 那現在有了 Flow Matching 這種更好的做法 等一下下一頁就告訴你 這個更好的做法是什麼樣子 非常的簡單
這個步數就可以看作是某種層數 但這個 Flow Matching Model 裡面往往不止一層 但如果我們把一個 Flow Matching Model 想成一層 那你如果說 我要用十步從左邊走到右邊 那你就可以說 愛為一個十層的深層式模型 用一千步就是一千層的深層式模型 接下來就要講 這個 Flow Matching 的 Network 怎麼被訓練出來的 這個是一個知難行易的典範
就是方法很簡單 那背後的理論很複雜 沒有辦法在今天講 怎麼很簡單 怎麼訓練剛才那個 Flow Matching Network 從 Source Distribution Sample 出一個點叫 X0 從 Target Distribution Sample 出一個點 這些點都是一個向量叫 X1 把他們連起來 在他們的連線上面取一個點 那怎麼決定要在連線上面取哪一個點
你會先從 0 到 1 之間 Sample 一個數值 叫做 T T 是一個介於 0 到 1 之間的值 然後你把 X0 乘 1 減 T 再加上 X1 乘 T 就是他們兩個中間連線的某一個點 那如果 T 正好 Sample 到 1 那你就是到 X1 這邊 T Sample 到 0 就到 X0 這邊 所以 T 如果比較接近 1 就是往 X1 靠 T 如果比較接近 0
就是往 X0 靠 Sample 出這個東西以後 接下來 Flow Matching Model 學的就是 在這個點 在 T 這個時間 你要輸出的方向是什麼 要輸出的方向就是 X1 減 X0 我們把 X1 減 X0 叫做 V 你要跟 Flow Matching Model 說 以後這個嚮導要學會說 以後有人問你在這個點
然後在 T 這個時間 要怎麼走 你就說往 X0 到 X1 的方向走 就這樣 就訓練下去 然後一筆資料是不夠的 你會 Sample 很多筆資料 你在 Sample 另外一筆資料 Sample 另外一筆資料 連起來 中間取一個點 然後你再告訴 Flow Matching Model 說 以後有人在這個點 在 T 的時間
問你說接下來要怎麼走 你就說從 X0 走往 X1 這個方向 以後訓練完之後 如果在這個位置 你問 Flow Matching Model 說 如果在 T 的時間要怎麼走 它就告訴你往這個方向走 在這個位置 你說現在是時間 T 要怎麼走 它就告訴你往這個方向走 然後就沒有然後了 訓練下去
就得到了 Flow Matching Model 你就得到了你的 Vector Field 你就得到了一個嚮導 接下來是一個範例程式 告訴你說 Flow Matching Model 是怎麼運作的 好 那我們來示範一下 Flow Matching Model 先 import 一些 Library 然後我們先產生一個 簡單的 Source Distribution 跟一個簡單的 Target Distribution 那我們的 Source Distribution 呢
就是一個 Gaussian Distribution 它的原點就在 這個 00 的地方 那我們就是定義了一個 function 叫做 Sample Source Distribution 它是一個數字 這個數字代表我們要 Sample 幾筆資料出來 所以我這邊就說 Sample Source Distribution 時 它就給我 10 筆 從這一個分布 Sample 出來的資料 那一樣我們要有一個 Target Distribution 我們 Target Distribution
是有兩個 Gaussian 合在一起的 是一個 Gaussian Mixture Model 那這個 Target Distribution 呢 我一樣叫它 Sample Target Distribution 後面接個數字 代表我們要 Sample 幾筆資料 那我們就說 Sample Target Distribution 時 我們就從 Target Distribution Sample 10 筆資料 當然看這些數字 你很難知道它長什麼樣子 你只知道我們是在二維的空間中做 Sample
但你不知道它分布長什麼樣子 我們把 Source Distribution 跟 Target Distribution 各 Sample 500 筆出來 然後畫在二維平面上給你看一下 好所以這個藍色的點 是我們的 Source Distribution 綠色的點是我們的 Target Distribution 我們就是希望透過一個 Neural Network 的轉換
把藍色的點變成綠色的點 好怎麼做呢 我們就用 Flow Matching Model 首先要定義我們的 Flow Matching 的 Network 那我們 Flow Matching 的 Network 的形狀呢 就是它要輸入一個二維的向量 輸入一個代表時間的 Scalar 所以它輸入其實是一個三維的向量 然後就輸出另外一個二維的向量
告訴要走的人說 我們現在要往哪個方向走 所以就定義了一個 Network 輸入是三維的向量 輸出是二維的向量 那它就是三個 Hidden Layer 一個非常簡單的 Neural Network 它有兩個 Hidden Layer 一個非常簡單的 Neural Network 然後接下來
我們要定義怎麼產生我們的訓練資料 我們定義一個函式叫做 Get Training Data 這 Get Training Data 它的工作 就是幫我們產生訓練資料 所以 Get Training Data 會給它三個輸入 一個輸入就是來自 Source Distribution 的向量 一個輸入是來自 Target Distribution 的向量 還有我們 Sample 的時間 T
然後它根據這三個東西 它就創造出一個 Source Distribution 跟 Target Distribution 這兩個向量的 Interpolation 然後再加上時間 那這個是要等一下訓練資料的輸入 然後輸出呢 輸出就是 X1 就是這個方向 就是 X1 這個方向 所以輸出我們的 Label
其實就是 X1 這個方向 所以我們有 Get Training Data 這個函式 它會幫我們產生訓練資料 好 再來就很簡單了 再來就是開始訓練 那怎麼開始訓練呢 你就是用這一個 Get Training Data 去產生大量的訓練資料 這個是輸入 這個是輸出 去訓練那個 Flow Matching 的 Network 教這個 Flow Matching 的 Network
看到這個三維的向量 其中兩維代表的是一個 Interpolation 的結果 第三維代表是時間 就要輸出這個兩維的向量代表 接下來應該要怎麼走 然後就是 Train 下去 當然這邊的 Training 就跟一般的 Training 差不多 你就要設個要幾個 Epoch Batch Size 要多大 要用什麼樣的 Optimizer 這個 Training
都是跟一般的 Training 是一樣的 好 那我們就是訓練下去了 好 就訓練下去 好 那你就會看到 Loss 是會下降的 那這個跟一般的訓練是沒有什麼不同的 好 訓練完之後 就有那個 Flow Matching Model 了 我們就來跑一下這個 Flow Matching Model 吧 那這個 Flow Matching Model 運作的原理 我們剛才已經講過 首先你要定義說
從開始到結束 我們要走幾步 然後呢 Flow Matching Model 就用那個固定的步數 會把從 Source Distribution 來的點 移到 Target Distribution 但可以想像說這個步數如果越多 你走最終的結果就會越精準 如果步數很少 那結果就很差 步數多就會比較精準 但步數多的壞處就是
你需要比較多的運算資源 好 看一下 Flow Matching Model 的運作 我們這邊的步數呢 先設個十步 好 這個 Number of Generation Step 等於 10 代表 我們就說我們的旅程呢 從左邊走到右邊要十步 好 你就可以看到說 我們出發是從藍色的點出發 好 這些藍色的點 我把它們的路徑 移動的路徑 用紅色的線把它畫出來
你就看到藍色的點呢 就分成兩邊 有些人往上 有些人往下 那這個 這些 這邊你可以看到 有一些黃色的點呢 沒有走得很好 它還沒有走到 終點 所以這個黃色的點的分布 就是最終從藍色的點 通過 Flow Matching Model 指引得到黃色的點 看起來黃色的點 跟這個綠色的點 還沒有非常的像
好 那這個 這個步數啊 你真的不能設太少 比如如果設一步 設一步 就只用 Flow Matching Model 引導一步 你會發現 完全做不了啊 就是這些綠色的點 這些藍色的點 就是移到兩組綠色的點之間 那你的這個黃色的點 跟這個綠色的點呢 它分布是差距很大的 所以這個 Flow Matching 的數字呢 這個步數的那個數字呢
一定要夠大 結果才會好 比如試個三點 就看起來好一點 那我們如果設多一點呢 我們設個 50 步看看 你看就結果跟剛才相比就好很多 那我們產生的黃色的這些點的分布 就跟綠色的點的分布 又跟剛才十步相比 又更接近一點 這個就是 Flow Matching 可以想說這個綠色的分布太簡單了
做一個更難的 我們定義一個另外一個 Target Distribution 然後把這個 Target Distribution 畫出來看一下 那這個 Target Distribution 這一次是一個螺紋的形狀 所以我們要把這些藍色的點 分布到這個螺紋的形狀上 那我們看看 Flow Matching 能不能成功 那套用剛才一模一樣的做法 我們來 Train 看看 Train 個 Network
Train完了 Train完以後呢 我們來繪製一下生成的過程 看看行不行哦 看起來不行啊 我先看步數設多少 50 步 其實也夠了 但是 這個綠色的點 移動之後是變黃色的點 它是散布成一團 它沒有跟綠色的目標 這個藍色的點變成黃色的點以後
沒有跟綠色的目標很接近 這個不行 沒有成功 所以其實呢 Flow Matching 呢 你還是要調參數的 因為我們現在有一個 Neural Network 嘛 那我們要確保那個 Neural Network 能夠 fit 它的 training data 所以我們調個參數 調什麼參數呢 Layer 加寬加深 這個 typical 的做法 把這個 Flow Matching 的 Net 弄大一點 其實這邊還有很多不同的改法
比如說我這邊是直接把時間跟位置 concatenate 在一起 所以對模型來說 它得花一點時間才知道說 誰是時間誰是位置 那你其實可以把兩組數字 用不同的方法來處理 不過這邊就不做那麼麻煩的事 然後這邊就是跑多一點 Epoch train 下去看看啊 好這邊就要等一下啦 我們就等一下 正好休息一下 緩慢的跑 緩慢的跑
讓它緩慢的跑 就焦躁的等待 平常是不是常常這樣子 焦躁的等待模型訓練的過程 就看看它上上下下上上下下 如果它能夠到三以下的話就高興了 然後如果它三以上的話就難過了 這樣子 它現在看起來應該是可以弄到三上下 經驗弄到三上下的話基本上就是成功了 現在進入二點多的區間 好訓練完成了
然後繪製生成的結果 這邊一樣是設 50 步哦 我們來看看結果怎麼樣 誒就可以了 就是這麼神奇 所以這些藍色的點通過 50 步以後 它會變成黃色的點 而這些黃色點的分布 跟這個螺紋的形狀 是非常接近的 然後呢 我有把它這個移動的過程啊
也把它 visualize 出來 讓你可以更能夠想像 在整個旅程中發生了什麼事 我們現在只看到旅程的開頭 就是藍色的點 那個旅程結尾就是黃色的點 那我們來看看旅程中 一路上發生了什麼樣的事情 所以現在就是把那個旅程呢 把它花一點時間 把它畫出來 好我們現在呢 就是把旅程做一個動畫
把它的旅程呢 畫出來 你看哦 它散開來 它散開來 好從頭開始 你可以看發現它一開始是先深呼吸 所有黃色的點居然是先往內集中 然後才往外移動 就是這麼神奇 一開始所有的點都想往內走
那直到某一個時間之後 才會有一些點往外移動 那外面的這個紅色的箭頭啊 是代表這個 Flow Matching 的那個 Network 給我們的那個 vector field 它指引的方向 長什麼樣子 那就可以看到說 這個 vector field 是會隨時間改變的 一開始所有的箭頭都指向中間 所以所有的點都往中間跑
然後接下來 內部有一些箭頭開始往外 然後所以點呢 就被往外擴散 然後它就學到這個東西 然後可以把藍色的 Distribution 變成綠色的 Distribution 就是這麼神奇 好 那如果講什麼 Flow Matching 你沒有聽得很懂的話 也沒關係 反正這邊就告訴你說 有一系列的技術 叫做 Generative 的 Model
它們能做到的事情 就是你可以從某一個 Distribution 裡面的 Sample 點 它把它變成另外一個 Distribution 那其實過去呢 Generative Model 是可以單獨使用 拿來生成圖片的 並不一定要搭配 Autoregressive 的 Model 因為一張圖片 也可以視為一個非常高維的向量
如果我們把一張圖片視為一個非常高維的向量 生成模型這種 Generative Model 又可以產生這種高維的向量的話 那我們直接拿生成模型 來直接一次產生一張圖片 其實就可以了 也不一定要用到 Autoregressive 的 Model 那在 2022 年之前呢 通常影像生成就是這樣做的 用這個 Diffusion Model
可以直接產生一張圖片 那後來隨著時代演進啊 人們知道說直接產生一張圖片 直接產生這個 pixel 有點困難 也許我們還是可以把 pixel 簡化一下 簡化成 比如說 continuous token 我們用 continuous token 來表示一張圖片 一張圖片對應的 continuous token 全部集合起來
其實也是個高維的向量 所以我們可以用生成模型 Diffusion Model 或 Flow Matching Model 直接產生代表一張圖片的 所有的 continuous token 然後再把這些 continuous token 排起來 通過 Detokenizer 也可以產生圖片 所以這些 Generative Model 是可以單獨使用的 但我們現在來看
那其中一個很知名的代表 就是 Latent Diffusion Model 它就是這個 Stable Diffusion 這個知名模型的核心技術 那如果想要知道 Latent Diffusion Model 怎麼運作的 可以看一下以下這個 2023 年機器學習上課的錄影 好接下來就要講兩條世界線的匯聚 Autoregressive Model 跟 Generative Model
怎麼被結合在一起 好我們剛才講說 Generative Model 它可以輸出一個機率分布 我剛才講 Autoregressive Model 你在輸出 continuous token 的時候 是有困難的 這個困難就可以套用 Generative Model 的想法來解 本來一個接龍的模型 如果你跟它講說 你要跟某一個 Distribution
越接近越好 它做不到 你用 MSE 做不到 它輸出就是個向量 怎麼跟一個 Distribution 越接近越好呢 但是我們可以把 Generative 的概念 套到這些接龍模型裡面 這些接龍模型 每次在生出一個 token 的時候 它要先從 Normal Distribution 做一下 Sample 從 Normal Distribution Sample 一個向量出來 這樣它的輸出
也會變成一個 Distribution 我們就可以讓輸出的 Distribution 跟我們的目標的 Distribution 越接近越好 那這邊啊 這個 Generative Model 就可以套用不同的模型 你可以套用 Diffusion Model 那我們就說它是用了 Diffusion Loss 你可以套用 Flow Matching Model 那就說它用的是 Flow Matching Loss 這邊可以套用 各式各樣的 Generative Model
套用在這個地方 但是啊 像這樣的模型 在 inference 的時候會有問題 在 inference 的時候有什麼樣的問題呢 我們剛才說 這是一個接龍的模型 你要產生圖片 已經輸入文字 已經產生前面幾個 continuous token 你要產生下一個 continuous token 在產生之前 你要先從 Source Distribution 它通常是一個 Normal Distribution
做 Sample Sample 出一個 vector 出來 把這個 vector 丟給我們的接龍模型 接龍模型根據這個 vector 還有前面已經有的這些東西 產生下一個 vector 但是它的輸出啊 往往就不是最終答案 為什麼 因為 Diffusion Model 或 Flow Matching Model 在 inference 的時候 是需要跑多個 iteration 的
我們剛才講說 Flow Matching Model 你要設定一個旅行的步數 只有一步是做不好的 你要設個比如說 50 步 才可以得到比較好的結果 而這個 Transformer 在 Flow Matching Model 的這個框架下 它的定位就是那個 Flow Matching 的 Network 所以這邊其實你也要輸入時間啊 我們只是把輸入時間這件事情省略掉 所以其實你在跑這個 Transformer 的時候
如果你是用 Flow Matching 的 Loss 你把它當這個 Flow Matching 的 Model 來做 你其實是要跑多個 iteration 的 也就是從這裡 Sample 產生這個輸出以後 還沒完 產生這個輸出以後 它只是告訴你要走的方向而已 你要把這個輸出的方向 再加回去 然後再通過整個 Transformer 再得到新的輸出 這個過程 要不斷的往復執行
那就看你從 Source 到 Target 你想要走幾步 你設定走 10 步 這個 Transformer 就要跑 10 次 設定 100 步 Transformer 就要跑 100 次 那這個 Transformer 是一個龐然大物 你之前在 Language Model 裡生一個 token 你都蠻花時間了 更何況是現在每次生一個東西 都要跑 100 次 Transformer 呢 這個可能是在實作上 是很難接受的 所以後來就有一個新的想法
這個新的想法叫做 Generation Head 什麼意思呢 這 Generation Head 的意思是說 能不能把 Generative Model 的部分 跟這個接龍的部分 盡量切開來 這個負責接龍的模型 根據這些已經產生的結果 輸出一個向量 這個向量 並不是 這個 Flow Matching Model 裡面
輸出的那個要走的方向 Flow Matching Model 這個時候還沒有出現 Flow Matching Model 或其他 Generative Model 又在什麼地方呢 你這邊有一個 Normal Distribution 從這個 Normal Distribution Sample Sample 一個向量出來 把這個向量 跟這個向量合起來 丟給一個小的模型 這個小的模型叫做 Generation Head 這個 Generation Head 會輸出一個向量 這個東西
才是 Flow Matching Model 裡面 告訴每一個向量 要走的方向 要怎麼走 是這邊這個向量 那如果我們要跑多個 iteration 的時候 你這個向量 要拿回來 再跑下一輪 再跑下一輪 這個時候你會發現 因為這個藍色的向量 是固定的 你完全不需要通過 這個巨大的 Transformer 如果你可以讓這個 Generative Model 非常的簡單
那今天在實作上 可能就是一兩層的 MLP 就讓它非常簡單 一個小小的模型就好 那你在跑多個 iteration 的時候 你只需要跑過這個小模型 那就可以節省 非常大量的算力 這個就是 Generation Head 的概念 那這個 Generation Head 你在實作的時候 可以用 Diffusion Model 來實作 那你有的就是 Diffusion Head 比如說 何凱明有一篇 paper
這是去年年中的時候的文章 他的標題是 Autoregressive Image Generation Without Vector Quantization 他就是做了 他就提出了這個方法 然後 Generation Head 是一個 Diffusion Head 那你可以想像說到去年年中的時候 要怎麼處理 continuous generation 仍然是一個大家不完全知道的問題
所以他在標題裡面才告訴你說 這篇 paper 的重點是什麼 他這篇 paper 的重點就是 你不再需要做 Vector Quantization 了 你不再需要 Diffusion 的 token 了 他想了一個方法 可以讓模型輸出 continuous 的 token 那這邊再講一下 這整個生成的過程是怎麼回事 這整個生成的過程就是 你一開始有一段文字 根據這段文字輸出一個向量
然後你有一個 Normal Distribution 根據這個 Normal Distribution 去做一個 Sample Sample 完之後 丟給一個 Generation Head 這個 Generation Head 輸出一個向量 這不算完 這邊要跑多個輪迴 跑多個迴圈 然後才能夠產生一個向量 產生一個向量之後 產生一個 continuous 的 vector 之後 continuous 的 token 會當做下一次的輸入
然後再產生下一個 vector 然後再從 Normal Distribution Sample 一次 再有 Generation Head 再產生新的向量 然後這邊也要跑多個輪迴 才會產生一個 continuous vector 所以產生一個 continuous token 都是需要跑多個 iteration 都要用多次 Generation Head 才能夠產生一個 continuous 的 vector
所以你要產生一張完整的圖片 你要產生一大排的 continuous vector 產生每一個 continuous vector 你也要跑多個 iteration 雖然這個 Generation Head 已經盡量簡單了 但是跑多次的 Generation Head 仍然往往是一個非常花時間的事情 所以下一個階段 可以研究的一個重要的課題 就是怎麼讓 Generation Head 需要的 iteration 的數目
越少越好 但現在已經有很多相關的研究 大家可以再去查一些關鍵字 比如說 Rectified Flow 或者是 Energy Model 之類的東西 有很多方法都試圖 能不能拿掉 iteration 我們就想辦法做到一步生成 除了用 Diffusion Head 的話 當然也可以用 Flow Matching Head 你就把 Head
從用 Flow Matching 的想法來實作 就是 Flow Matching Head 比如說今年年中就有一個模型 叫做 Next Step One 它做的就是 Flow Matching Head 你看這個圖 還有這個文字接龍的模型 都跟我們講的觀念是一樣的 那這邊呢 文字接龍的模型呢 仍然可以套用任何我們剛才講過的技巧
比如說 MaskGIT 完全可以套用在這個地方 它跟 Generation Head 的概念 是不衝突的 所以你可以有 MaskGIT 又有 Generation Head 所以完全可以把 MaskGIT 裡面的 token 就換成這些 continuous 的 token 然後被 Mask 起來的地方 要輸出一些向量 這些向量不是最重要的答案 這些向量要搭配
從 Gaussian Distribution Sample 出來的東西 通過 Generation Head 跑多個 iteration 才能夠得到最終的結果 總之 Generation Head 的概念 跟文字接龍的部分是不衝突的 你可以套用任何 你覺得最好的文字接龍的方法 加上 Generation Head 那像剛才不是講了一個 VAR 它說模型呢 這個影像生成的時候呢
有兩層的 Generation 有兩層的 Autoregressive 每一張圖片生成的時候 Autoregressive 有一個從小到大的 Autoregressive 用同一個 Model 來做 這是 VAR VAR 也完全可以加上 continuous 的 token 套用 Flow Matching 的結果 那就是從 VAR 變成 Flow AR
那這樣子的想法就是一個接龍模型 套用 Generation Head 的方法 2025 年看到了非常多好的結果 還有非常多的應用 比如說有一系列的 work 是拿這樣的模型 是拿這樣的模型拿來做文字生 audio 拿文字生 audio
就是你跟模型說我要產生一個火車站的聲音 有人在講話 火車開過這樣子的聲音 那這兩篇文章呢 是我們實驗室的黃冠博同學跟那個楊書文同學去 Amazon 實習的時候 做的 work 然後呢像 TTS 但是現在也有一些很好的模型是用類似 Generation Head 的方法來實作的
那這邊它其實用的甚至不是 Flow Matching Model 它用的是一個更進階的方法叫做 Energy 的 Model 可以用很少的 iteration 就產生好的結果 那這也是幾個月前的事情 或者是有人做這個語音到語音的 Speech Language Model 那也可以用 Flow Matching Head 的方法來做 那或者是 Video Generation 也有 Video 的 VAR
這邊 paper title 就是 Autoregressive Video Generation with Continuous Token 要生成 continuous token 你就要套用 Generation Head 的想法 總之這樣的 work 在 2025 年看到多 看到非常多的發展 好總之我們現在 2025 年看到的就是兩條世界線的結合 今天就是告訴大家在 Diffusion Model 以外的另外一條世界線
還有它們是怎麼被結合在一起的
Loading video analysis...