量的關(guān)鍵機制)
AI作曲這幾年火得不行從隨手哼兩句變成完整的編曲再到給短視頻配BGM幾乎每個環(huán)節(jié)都有模型的身影。但真正上手做過音樂生成項目的人都會撞上同一個尷尬開頭兩小節(jié)驚艷八小節(jié)之后開始原地轉(zhuǎn)圈到十六小節(jié)基本已經(jīng)忘了前面在寫什么。旋律不停重復(fù)、和弦走向莫名其妙突變、主題動機走著走著就丟了問題并不在“模型不會寫曲子”而在于模型根本“沒記住自己寫過什么”。這篇文章想聊的就是AI作曲里那個經(jīng)常被忽視、卻決定生成質(zhì)量上限的關(guān)鍵機制——短期記憶。標題里的“秘密”不是故弄玄虛。過去兩年我先后做過幾次音樂生成方向的嘗試從最早基于規(guī)則拼接的MIDI生成到后來用序列模型做旋律續(xù)寫再到帶注意力結(jié)構(gòu)的生成方案越到后面越發(fā)現(xiàn)決定一首AI曲子是“能聽”還是“沒法聽”的往往不是生成網(wǎng)絡(luò)有多深、訓(xùn)練數(shù)據(jù)有多大而是它在生成過程中怎么處理和保留已經(jīng)輸出的歷史信息。這個機制放到深度學(xué)習里多數(shù)時候表現(xiàn)為注意力窗口、緩存狀態(tài)或者隱向量放到音樂層面它就是模型的短期記憶。它能決定模型是死守著一兩個動機反復(fù)倒帶還是有能力讓音樂在幾十秒內(nèi)流動起來、發(fā)展下去。這篇內(nèi)容適合正在做音樂生成、旋律續(xù)寫、AI編曲相關(guān)項目的朋友參考也適合那些好奇“為什么AI寫的歌總有股莫名其妙的重復(fù)感”的人。我會從記憶機制的本質(zhì)講起結(jié)合自己做過的幾個實驗把這套東西拆開揉碎包括模型結(jié)構(gòu)上的取舍、實際訓(xùn)練中的參數(shù)策略以及那些不跑幾個通宵絕對發(fā)現(xiàn)不了的坑。1. 音樂生成里的“記憶”到底指什么很多人第一次接觸AI作曲以為模型是“理解”了音樂才寫出來的。實際上到目前為止主流的生成模型本質(zhì)上做的是條件概率預(yù)測也就是給定前面已經(jīng)生成的音符序列預(yù)測下一個最合理的音符是什么。聽起來好像很簡單但這里有一個隱藏前提為了讓“下一個音符”合理模型必須知道“前面的音符”到底發(fā)生了什么。這個“前面”的范圍有多大信息能被記住多少就是短期記憶要回答的問題。1.1 從人的創(chuàng)作習慣理解短期記憶的必要性人類作曲家作曲的時候短期記憶的作用太明顯了。隨便寫一段八小節(jié)的旋律你會發(fā)現(xiàn)第一小節(jié)和第二小節(jié)往往存在某種呼應(yīng)第三、四小節(jié)會有一點發(fā)展到了第七、八小節(jié)可能又回到開頭的元素。這不是偶然而是創(chuàng)作者在落筆的時候腦子里始終保留著前面音樂片段的“余音”知道現(xiàn)在這句是從哪來的、要往哪去。專業(yè)的說法叫主題發(fā)展或者動機貫穿翻譯成大白話就是創(chuàng)作者記得自己寫了什么。AI模型呢如果模型架構(gòu)里沒有足夠的記憶能力那它本質(zhì)上就是一個隨時“失憶”的創(chuàng)作者。它生成第100個音符的時候可能完全不記得第1個音符長什么樣只能靠最近一小段信息瞎猜。結(jié)果就是旋律不停地在局部打轉(zhuǎn)——因為最近的幾個音符可能剛好構(gòu)成了一個穩(wěn)定的進行模型覺得“這地方很安全”就反復(fù)往相似的方向走。這就是大家常說的AI音樂“幾秒鐘后開始復(fù)讀”的根本原因。1.2 短期記憶和長期記憶在技術(shù)上的分界順著這個思路往下模型記憶能力的討論通常會分成兩個層次。短期記憶一般指模型在生成當前音符時能直接“看到”或“讀取”到的上下文信息。在Transformer類模型里就是這個意思生成的時候前面生成的所有token都會通過注意力機制參與當前步的計算。窗口有多長記憶就有多大。長期記憶則不一樣它更接近于“模型從訓(xùn)練數(shù)據(jù)里學(xué)到的規(guī)律”比如大調(diào)里導(dǎo)音傾向于解決到主音比如四小節(jié)通常構(gòu)成一個樂句。這些東西已經(jīng)不依賴具體某一次生成的上下文了是沉淀在權(quán)重里的經(jīng)驗。這兩者很容易被混淆。經(jīng)常有人跟我說“我的模型學(xué)了很多莫扎特為什么生成的東西還是不像”問題往往出在短期記憶不夠模型學(xué)到了莫扎特的和聲規(guī)則卻記不住自己在前八小節(jié)里已經(jīng)用了什么素材。1.3 為什么音樂比其他序列任務(wù)更依賴短期記憶文本生成也依賴上下文但音樂生成對短期記憶的要求有它非常特殊的地方。音樂的核心結(jié)構(gòu)特征在于“重復(fù)中的變化”——同一個動機反復(fù)出現(xiàn)每次出現(xiàn)都要有細微的變化這需要模型既記得動機的原型也記得每次變化后的差異。這和語言不同語言里一個詞錯了語義可能就偏了但音樂里同一個旋律原樣重復(fù)多遍或者變化得離譜都可能成為“聽感崩塌”的元兇。具體到數(shù)值上一段120BPM的四四拍音樂一小節(jié)大約兩秒一個典型的樂句是四小節(jié)也就是八秒。要讓模型生成的音樂聽起來有結(jié)構(gòu)感它至少需要記住過去四到八小節(jié)的素材換算成音符數(shù)量大概就是64到128個音符假設(shè)每拍兩個音。這是非常高的記憶要求比大多數(shù)文本生成的上下文要密集得多因為音符相對簡單信息熵卻靠排列組合撐得很高。2. 藏在Transformer和RNN里的記憶機制聊完了“為什么需要記憶”再說說當前主流模型到底是怎么實現(xiàn)記憶的。這里繞不開兩種最常見的架構(gòu)路徑一種是以自注意力為核心的Transformer方案另一種是更早期的循環(huán)神經(jīng)網(wǎng)絡(luò)方案。兩種方案對短期記憶的理解完全不同實現(xiàn)方式也各有優(yōu)劣。我個人的經(jīng)驗是了解這兩條路才能在實際項目里做出合適的選擇。2.1 Transformer的注意力窗口就是顯式的短期記憶現(xiàn)在音樂生成用得最多的一般是Transformer家族。它的短期記憶機制非常直觀生成第t個音符的時候模型會把第1到第t-1個音符的表示全部拿出來跟當前步做注意力計算。理論上只要窗口夠長模型就能“記住”從樂曲開頭到現(xiàn)在的所有信息。這個設(shè)計非常優(yōu)雅也讓訓(xùn)練過程變得簡單直接。但“理論上”三個字后面通常跟著一個“不過”。注意力窗口長不代表模型真的會用這些信息。如果訓(xùn)練數(shù)據(jù)里大部分曲子并不需要特別遠距離的依賴模型學(xué)到的注意力權(quán)重會自然地偏向相鄰音符遠端的信息雖然在那里注意力卻很少分配過去。這就好比一個學(xué)生桌上擺了一整套教材但他復(fù)習的時候只看最近兩頁那遠端教材對他考試成績的影響幾乎為零。所以不少團隊在Transformer之外還要引入一些機制來“強制”模型看重遠處的信息這個后面會詳細說。2.2 KV Cache工程實現(xiàn)里最容易被忽略的記憶載體如果真正去實現(xiàn)過基于Transformer的自回歸生成大概率會遇到一個叫KV Cache的概念。它的全稱是Key-Value Cache作用是緩存已經(jīng)計算過的注意力鍵值對避免每一步都從頭算一遍前面的內(nèi)容。在推理解釋上這就是Transformer的“短期記憶倉庫”生成第10個音符時前9個音符的K和V向量都存在緩存里直接取出來參與計算。這里有一個很多初學(xué)者容易忽略的事實窗口長度決定了KV Cache的大小而KV Cache的大小直接跟延遲和顯存掛鉤。在音樂生成場景里如果序列很長比如生成一整首鋼琴曲的子旋律可能有幾千個音符KV Cache會持續(xù)膨脹推理速度越來越慢。我自己跑實驗的時候出現(xiàn)過生成前幾十個音符飛快、后面越來越慢的情況一開始還以為是模型出問題了后來才發(fā)現(xiàn)就是KV Cache吃滿了顯存。為了控制這個問題的常見做法是限制注意力窗口長度或者用滑動窗口注意力只讓模型關(guān)注最近N個token。# 偽代碼示例限制注意力窗口的KV Cache保留范圍 def generate_with_sliding_window(model, token_ids, window_size128): cache_k, cache_v [], [] for t in range(len(token_ids)): start max(0, t - window_size) context token_ids[start:t 1] k, v model.encode(context) cache_k.append(k) cache_v.append(v) if len(cache_k) window_size: cache_k.pop(0) cache_v.pop(0) logits model.decode(cache_k, cache_v) next_token sample(logits) return next_token2.3 RNN的隱狀態(tài)另一種形態(tài)的短期記憶Transformer流行之前音樂生成領(lǐng)域其實走過很長一段RNN的路。LSTM和GRU這類循環(huán)網(wǎng)絡(luò)沒有顯式的注意力窗口它們的記憶全部裝在一個固定維度的隱狀態(tài)向量里每生成一個音符隱狀態(tài)被更新一次。如果說Transformer的短期記憶是一本可以被隨意翻閱的筆記本那RNN的短期記憶就像一個人腦中的印象容量有限而且越久遠的內(nèi)容越容易被壓縮、變形。這就帶來了一個非常有意思的對比RNN因為隱狀態(tài)容量有限天然會把遠近信息做壓縮處理早期信息很容易被后續(xù)信息“覆蓋”生成出來的旋律后段離前段越來越遠而Transformer因為保留全部歷史token理論上可以做到“每一頁都被記得清清楚楚”但也正因為記得太清楚反而可能讓模型偷懶——它發(fā)現(xiàn)只要參考最近幾個音符就能把下一個音符預(yù)測得差不多就不會刻意去挖掘遠端的結(jié)構(gòu)線索。說句實在話這兩種模型在音樂生成上各有各的難纏。2.4 為什么說位置編碼是短期記憶的坐標系統(tǒng)理解了注意力機制之后還有一個細節(jié)不能跳過位置編碼。注意力計算本身是不分先后順序的它把序列當成一個集合來處理。如果沒有位置信息模型就分不清“前面出現(xiàn)過的主旋律”和“剛過去的那一下裝飾音”在時間上的差別。所以幾乎所有的Transformer模型都會在輸入里加入位置編碼讓每個token帶上“我是第幾個出現(xiàn)的”這個信息。在音樂生成任務(wù)中位置編碼還有一個比較特殊的意義它不僅標記順序還直接影響模型對節(jié)奏和時值的感知。不同的音符有不同的時值同樣的音高出現(xiàn)在第一拍和第三拍含義完全不同。如果把音樂token化之后再加上絕對位置編碼模型等于拿著一個刻度尺去丈量記憶里的事件這對生成穩(wěn)定的節(jié)奏律動非常重要。我見過一個實驗把絕對位置編碼換成相對位置編碼之后模型生成的三連音明顯更穩(wěn)定了因為相對位置讓模型在記憶里更容易識別“從這個音往后推多少拍是下一個重音”這類規(guī)律。3. 我踩過的短期記憶工程坑這一節(jié)說說實操。我做過幾次嘗試踩過不少坑。有些問題看起來是模型能力不行結(jié)果排查到最后發(fā)現(xiàn)問題出在對短期記憶機制的理解上。挑幾個印象深刻的跟大家聊聊都是真實遇到過的場景。3.1 復(fù)現(xiàn)某開源作曲模型時發(fā)現(xiàn)生成永遠停在三小節(jié)有一次我復(fù)現(xiàn)一個開源的旋律續(xù)寫模型訓(xùn)練了很久一到生成階段就出問題模型最多生成三小節(jié)新內(nèi)容之后就開始無限循環(huán)第一小節(jié)的節(jié)奏型偶爾換一兩個音但整體上已經(jīng)完全失去推進感。一開始我懷疑是訓(xùn)練數(shù)據(jù)的毛病后來檢查了推理代碼才發(fā)現(xiàn)問題出在我使用的窗口長度上。在那個模型的設(shè)計里訓(xùn)練時序列被切成了固定長度片段每個片段內(nèi)的信息最多跨越16小節(jié)但我的推理代碼把窗口長度錯設(shè)成了4小節(jié)等于模型只能看到過去1秒的內(nèi)容。打個比方一個只看了前兩頁書的人讓他續(xù)寫整本小說的后續(xù)情節(jié)他除了反復(fù)描述前兩頁出現(xiàn)的人物之外確實也沒什么別的辦法。這個排查過程提醒我短期記憶的窗口設(shè)置必須跟訓(xùn)練時保持一致不能只看模型文檔里寫的“支持長序列”還得自己確認推理階段的有效記憶范圍是多少。3.2 位置編碼類型選錯導(dǎo)致的“節(jié)奏崩潰”還有一個印象更深的坑出現(xiàn)在位置編碼的選擇上。當時我對比了兩種位置編碼方案一種是絕對位置編碼另一種是相對位置編碼。實驗結(jié)果顯示用絕對位置編碼訓(xùn)練出來的模型在短句子上表現(xiàn)不錯但生成長句子時逐漸出現(xiàn)節(jié)奏混亂——原本均勻的八分音符跑著跑著變成不均勻的附點節(jié)奏又莫名其妙地變回八分音符整個律動像喝醉了酒。翻論文的時候看到一個解釋說絕對位置編碼在長距離外推時會失去精度模型對“隔了多遠”這件事的感知會變得模糊。音符時值本身就是靠位置關(guān)系定義的信息距離感知一模糊節(jié)奏自然要出問題。換用相對位置編碼之后類似情況明顯減少。這里想給的建議是如果項目里的音樂對節(jié)奏穩(wěn)定性要求高優(yōu)先考慮相對位置編碼或者能處理任意長度外推的編碼方案不要為了省事直接用絕對位置編碼。3.3 部分記憶單元失效導(dǎo)致的主題丟失還有一種情況更隱蔽模型的記憶機制本身是完整的但訓(xùn)練過程沒有讓模型學(xué)會有效利用記憶。我做過一次對比實驗兩組訓(xùn)練數(shù)據(jù)完全相同唯一區(qū)別是一組在訓(xùn)練時給loss加了一個“對遠端token注意力權(quán)重”的正則化約束另一組不加。結(jié)果顯示加了正則化約束的那組生成結(jié)果的樂句結(jié)構(gòu)明顯更完整主題動機能在16小節(jié)后重新出現(xiàn)而不加的那組前8小節(jié)和后8小節(jié)聽起來像是兩首不同的曲子。這讓我意識到對很多序列模型來說短期記憶不只是“有沒有”的問題更重要的是“模型有沒有被訓(xùn)練去用它”。如果訓(xùn)練數(shù)據(jù)的句子普遍偏短模型就會形成一種惰性只關(guān)注近處信息就能把loss降得很低遠端的記憶通道雖然技術(shù)在但根本沒有被激活。后面我在設(shè)計訓(xùn)練策略時會專門構(gòu)造一些需要“回溯遠處主題”的訓(xùn)練樣本逼著模型學(xué)會使用短期記憶里的遠程信息。3.4 訓(xùn)練與推理窗口不一致帶來的性能鐵幕這個問題在工程上非常容易踩。很多模型在訓(xùn)練時用的是128 token的窗口但到了生成階段理想情況下想讓它一次性生成幾百上千個音符。如果你直接把推理窗口拉長到512甚至更長模型表現(xiàn)往往會斷崖式下降。原因也不難理解——模型在訓(xùn)練時根本沒看過那么長的上下文你讓它在一個陌生的“記憶長度”下工作它當然不知道該把注意力放在哪里。我個人的習慣是訓(xùn)練階段就至少準備兩檔窗口一檔用于常規(guī)訓(xùn)練另一檔偶爾用長窗口做一次“預(yù)熱式”微調(diào)這樣到了推理階段長窗口生成時的表現(xiàn)會穩(wěn)定很多。有人管這招叫窗口一致性訓(xùn)練也有人叫它課程學(xué)習本質(zhì)上都是在做一件事讓模型習慣在一個足夠長的短期記憶范圍里工作。4. 把短期記憶用到極致的幾個實戰(zhàn)做法聊完踩坑說說哪些做法在實際項目中是有效的。下面這些策略有的是從論文里看來的有的是我自己試出來的都在不同程度上解決過“AI記不住自己寫了什么”的問題。為了方便對照我用一個模擬的旋律續(xù)寫項目來串起這些方案。4.1 用“主題token”做顯式的記憶錨點第一個做法是在輸入序列里增加一個特殊的主題token用來表征整段音樂的核心動機。具體來說在生成每一段新音樂之前先把目前的“主題摘要”作為特殊token拼在序列的開頭。模型生成每個音符時除了能看到最近的內(nèi)容還能時不時注意到開頭那個代表主題的token相當于給短期記憶加了一個“書簽”。實現(xiàn)上并不復(fù)雜。在tokenization階段可以用一個小型的編碼器去壓縮前8小節(jié)的內(nèi)容得到一組向量然后把這組向量映射成一個或幾個special token插入到輸入序列的最前面。音樂生成時模型每走一步都會回頭“看”一眼這個錨點相當于逼著短期記憶留存最核心的信息。即便注意力窗口內(nèi)部的普通音符已經(jīng)被沖得很遠主題token仍然能被頻繁訪問起到一種壓縮記憶的作用。4.2 局部重復(fù)建模讓短期記憶自動形成結(jié)構(gòu)第二種做法更貼近音樂的本質(zhì)——重復(fù)。音樂好聽很大程度上是因為有呼應(yīng)與重復(fù)而這種重復(fù)發(fā)生后短期記憶里的信息密度會更高??梢詫iT設(shè)計一種輔助任務(wù)訓(xùn)練模型預(yù)測“當前這個小節(jié)是否與前面某一個小節(jié)相似”或者“當前旋律應(yīng)該在哪個位置回到前面的素材”。這種輔助任務(wù)不需要改動模型主體架構(gòu)只需要在訓(xùn)練loss里加一個額外的分類頭或者在數(shù)據(jù)構(gòu)造時做一下類似對比學(xué)習的采樣。效果非常明顯因為模型一旦學(xué)會“識別重復(fù)”它生成的時候就更容易主動構(gòu)建短距離的呼應(yīng)結(jié)構(gòu)樂句之間的黏合感會強很多。路徑依賴的角度看這也等于在引導(dǎo)模型主動去短期記憶里翻找以前的素材而不是每次都憑空創(chuàng)造新內(nèi)容。4.3 讓記憶窗口做“分段滑動”而不是“整體滑動”傳統(tǒng)滑動窗口是丟掉最老的token保留最近的N個token。這種做法有一個問題如果一首曲子的主題出現(xiàn)在第1小節(jié)而當前生成到第40小節(jié)滑動窗口早就把主題沖掉了。雖然理論模型可以通過位置編碼回溯但工程上很多實現(xiàn)會把窗口外的信息直接截斷。一種更穩(wěn)妥的做法是分段滑動。窗口分成兩部分固定長度的“全局段”和滑動更新的“局部段”。全局段始終保留開頭若干小節(jié)的摘要信息局部段則存放最近生成的細節(jié)信息。生成時模型同時看這兩部分相當于既有“長期的主題記憶”又有“短期的細節(jié)記憶”。我在模擬項目里試過這個方案生成60小節(jié)以上的曲子時前后結(jié)構(gòu)的一致性提升非常明顯遠勝于單純的整體滑動窗口。4.4 用Midi編碼的字段信息增強記憶強度還有一個偏數(shù)據(jù)層面的做法容易被技術(shù)文章忽略但效果很實在處理好MIDI事件本身的編碼密度。很多音頻/MIDI編碼方案會把音符的“位置、時值、力度、音高”全部分開成不同的token甚至有些方案會把休止符也切成多個邏輯碎片。這會導(dǎo)致一個問題同樣一段四小節(jié)的信息被拆成了一大串token短期記憶里裝的“噪音”太多有效音樂信息反而被稀釋。如果能把MIDI事件編碼成更緊致的token序列比如一個音符包含“起始位置、時值、音高”三元組一段四小節(jié)的旋律可能只需要32個token而分開編碼可能需要100多個token。同樣窗口容量下緊致編碼等于把短期記憶的有效容量翻了倍這對前文提到的高密度音樂信息需求是非常友好的。我一般會先用一個統(tǒng)計腳本來跑一下訓(xùn)練集平均每小節(jié)的token數(shù)再決定窗口大小這個習慣幫我避開了不少容量規(guī)劃上的坑。5. 生成時的記憶衰減診斷與調(diào)參建議實操到后面你會發(fā)現(xiàn)一個更折磨人的問題就算模型架構(gòu)和訓(xùn)練都沒問題生成時還是會遇到“記憶衰減”。這里說的衰減并不是顯存或者緩存問題而是生成過程中的累積誤差導(dǎo)致模型逐漸偏離初始主題越到后面越不知道自己在干什么。診斷這類問題需要一些可量化的手段而不是靠耳朵聽。5.1 用自相似矩陣量化檢查記憶留存檢查模型有沒有在“正確回憶”之前的素材一個好用的工具是自相似矩陣self-similarity matrix。把生成的一段MIDI轉(zhuǎn)成特征序列比如每個小節(jié)的音高輪廓或節(jié)奏向量然后計算兩兩之間的相似度畫成一張熱力圖。如果曲子存在主題重現(xiàn)熱力圖里會看到清晰的塊狀結(jié)構(gòu)如果模型已經(jīng)失憶熱力圖會呈現(xiàn)一片模糊的漸變或者完全散亂的結(jié)構(gòu)。我自己每次調(diào)整完配置都會拿這個矩陣看一眼再決定是否繼續(xù)訓(xùn)練或推理。它比單純聽音頻靠譜得多也方便橫向?qū)Ρ炔煌瑓?shù)下的生成結(jié)果。有一次我把訓(xùn)練窗口從128提升到256其他什么都不變生成的曲子自相似矩陣里明顯多出很多塊狀結(jié)構(gòu)說明模型確實開始利用更長的記憶跨度了。5.2 溫度與采樣策略對記憶利用的影響同樣一個模型溫度參數(shù)不同生成結(jié)果對短期記憶的利用程度會差很多。溫度偏低時模型傾向于選擇概率最高的token通常會緊緊跟隨最近的上下文容易出現(xiàn)局部循環(huán)溫度偏高時模型隨機性大容易脫離記憶約束寫一會兒就跑到陌生的區(qū)域。理想值取決于項目和風格但我建議以0.8到1.0為起點做小范圍網(wǎng)格搜索。還有一個容易被忽略的參數(shù)是top-p或top-k采樣。如果采樣范圍限制得太窄模型在選擇下一個音符時幾乎只看最近幾個音符給出的高概率候選遠端記憶對當前步的影響會被壓縮。稍微放寬采樣范圍等于給模型更多機會去檢索不同位置的記憶信息。這里面有一個平衡要摸索采樣太寬會亂采樣太窄會復(fù)讀找到那個臨界點生成質(zhì)量會上一大截。5.3 從損失曲面反推訓(xùn)練窗口是否合適訓(xùn)練階段的損失曲線也能透露短期記憶問題。如果訓(xùn)練loss下降很快但驗證loss一直偏高大概率是模型過度依賴局部上下文沒有學(xué)會使用更遠的記憶信息。這種情況有一個特征把驗證集里的序列截斷成更短的片段loss會明顯下降而如果用完整長度序列評估loss就很差。一旦出現(xiàn)這種情況最簡單的干預(yù)是人為構(gòu)造一些“遠期依賴”的訓(xùn)練樣本比如把一首曲子的開頭兩個小節(jié)拼接到結(jié)尾前面再要求模型預(yù)測“結(jié)尾應(yīng)該接什么”迫使它回去翻看序列前面的信息。這種做法雖然粗暴但效果直接。做過幾次之后模型的驗證loss通常會有可見的改善生成的樂曲結(jié)構(gòu)感也會上一個臺階。5.4 參數(shù)速查我常用的短期記憶相關(guān)設(shè)置最后整理一份我實際操作中常用的參數(shù)速查表給想動手試的朋友一個起點。這些參數(shù)不是標準答案但作為基線基本能跑通參數(shù)推薦起點調(diào)整方向說明注意力窗口長度256 token窗口過短時樂句會失去結(jié)構(gòu)過長則訓(xùn)練成本明顯上升滑動窗口分段比例全局段25%/局部段75%偏重主題一致性就加大全局段偏重細節(jié)豐富性就加大局部段位置編碼相對位置編碼對節(jié)奏穩(wěn)定性要求高時優(yōu)先選這類方案溫度0.8 - 1.0風格偏古典可以更低偏即興爵士可以更高top-p0.9 - 0.95采樣范圍過窄時主題重現(xiàn)有明顯下降訓(xùn)練窗口128與256混用以128為主按比例摻入256的樣本讓模型適應(yīng)長窗口主題token數(shù)量4 - 8個太少可能表達力不足太多會占用普通音符的記憶空間6. 未來方向短期記憶之外還缺什么短期記憶解決了AI作曲就順了嗎還遠遠不夠。我自己跑完這些實驗后有一個比較清醒的認識短期記憶解決的是“記得住”的問題但在音樂創(chuàng)作里比“記得住”更難的是“知道什么時候該忘掉什么”。人類作曲家寫一曲子的過程中不會事無巨細地保留每一個裝飾音的記憶他們會有選擇地記住主題、和聲走向、節(jié)奏骨架忽略那些無關(guān)緊要的細節(jié)。這種“選擇性記憶”機制目前的Transformer窗口式記憶是做不到的。業(yè)界也在往這個方向探索。記憶增強的Transformer把外部存儲跟模型結(jié)合模型學(xué)會從一個大內(nèi)存里讀取與當前最相關(guān)的片段而不只是盯著固定窗口。還有人在嘗試用分層結(jié)構(gòu)來處理記憶把音樂先壓縮成樂句級、段級的高層摘要再在低層生成細節(jié)信息。這些做法的共同點是開始把“記憶”當成一個可以主動控制的目標而不是結(jié)構(gòu)帶來的副產(chǎn)品。我相信接下來一兩年這個方向會有更多實用成果出來。7. 最后分享兩個實際使用中的小技巧作為收尾分享兩個我在實踐中覺得特別有用的技巧都很簡單但經(jīng)常被忽略。第一個技巧是生成后做“回看校驗”。當模型生成完一整段音樂后把最開始幾個小節(jié)的旋律抽出來跟中間某幾個小節(jié)的旋律做相似度對比如果相似度低于某個閾值就自動加一個懲罰項重新生成那一段。這相當于給短期記憶上了一道保險哪怕模型生成時忘了后處理也能把它拉回來。第二個技巧是刻意把主題動機放在訓(xùn)練序列的“中段”而不是“開頭”。很多模型對序列開頭的記憶都很好但對中間部分的記憶最差。如果訓(xùn)練時經(jīng)常讓主題動機構(gòu)出現(xiàn)在中段模型就會被逼著練出更強的中段記憶能力。這個做法有點反直覺但我試過幾次后生成長曲子的穩(wěn)定性確實好了不少。說到底短期記憶在AI作曲里的作用遠不止是技術(shù)指標層面的“上下文長度”那么簡單。它直接決定了一個模型到底是在“創(chuàng)作”還是在“碰運氣”。今天寫這篇文章也是希望更多做音樂生成的朋友能少走我曾經(jīng)走過的彎路。如果你們在實踐中也遇到過其他跟記憶相關(guān)的坑歡迎一起交流。