--- slideOptions: transition: slide --- # SigLIP論文解析 <!-- Put the link to this slide here so people can follow --> Sigmoid Loss for Language Image Pre-Training --- ## 為何提出? 1. CLIP中的Softmax loss的計算量大、多GPU下浪費記憶體空間 2. CLIP訓練所需Batch size大,需要更多GPU --- 以下是[CLIP](https://arxiv.org/pdf/2103.00020)的pseudo code <font size=3>與SigLIP原文中方法3.1公式一致</font> ``` python #1.將Batch中的圖片-文字對進行編碼 I_f = image_encoder(I) #[n, d_i] T_f = text_encoder (T) #[n, d_t] #2.L2正規化統一範圍 #joint multimodal embedding [n, d_e] I_e = 12_normalize(np.dot(I_f, W_i), axis=1) T_e = 12_normalize(np.dot(T_f, W_t), axis=1) #3.比對[n, n]矩陣內所有元素的餘弦相似度,計算出相似度矩陣 # scaled pairwise cosine similarities [n, n] logits = np.dot(I_e, T_e.T) * np.exp(t) #4.對每一行(圖像)每一列(文本)為錨點做Cross Entropy loss labels = np.arange(n) loss_i = cross_entropy_loss(logits, labels, axis=0) loss_t = cross_entropy_loss(logits, labels, axis=1) loss = (loss_i + loss_t)/2 ``` ---- 其中第三步[n, n],這個矩陣包含了所有可能的圖像-文本配對的相似度得分,這就導致計算Cross Entropy時其中的softmax必須歷遍整個矩陣,複雜度$O(n^2)$ ![image](https://hackmd.io/_uploads/SJZTFiR31l.png) --- ## Siglip loss --- 以下是Siglip在計算loss部分的pseudo code ```python # img_emb :Image model embedding [n, dim] # txt_embA :text model embedding [n, dim] # t_prime, b : learnable temperature and bias # n :mini-batch size t = exp(t_prime) zimg = l2_normalize(img_emb) ztxt = l2_normalize(txt_emb) logits = dot(zimg, ztxt.T) * t + b #計算相似度 labels = 2 * eye(n)- ones(n) #創建一個1,-1的對角矩陣 l =-sum(log_sigmoid(labels * logits)) / n # 計算sigmoid取log ``` ---- 對角矩陣正的部分,對應到的圖文在資料集內一定是互相匹配的,即正樣本一定是1,負樣本都是-1,對於模型而言,變成只需要獨立判斷每個圖文對是正是負的二分類問題,不需要去理會其他樣本的概率 ![image](https://hackmd.io/_uploads/SJKjDaJakx.png) ---- $L = - \frac{1}{|B|} \sum_{i=1}^{|B|} \sum_{j=1}^{|B|} \log \left( \frac{1}{1 + e^{z_{ij}(-t x_i \cdot y_j + b)}} \right)$ * $-t x_i \cdot y_j + b:$計算正負相似度,b設計用於緩解初期負樣本過多的情況,t用於調整決策邊界的清晰度 * $z_{ij}$ 是標籤,如果第 $i$ 個圖像和第 $j$ 個文本是匹配的(即 $i=j$),則 $z_{ij} = 1$,否則 $z_{ij} = -1$ * $\log \left( \frac{1}{1 + e^{z_{ij}(-t x_i \cdot y_j + b)}} \right)$ 計算log Sigmoid --- ## 為什麼SigLip能提升分散式運算效能? 傳統對比式學習方法多採用data parallelism,將批次內的圖文分散到不同GPU,GPU上有相同的模型計算embeddings ![image](https://hackmd.io/_uploads/Hyg6_1e6Jg.png =650x) ---- * 計算Loss並更新時,因為需要計算整個批次內所有的圖文相似度,會採用All-Gather蒐集每個GPU上的embeddings * [All gather](https://blog.csdn.net/cy413026/article/details/138618053):所有的數據要讓所有裝置知道 * 每個GPU記憶體需要$(batch大小)^2$ * 傳輸成本高,記憶體效率低下 ![image](https://hackmd.io/_uploads/r1NchygTye.png) ---- 將一個Batch根據裝置數量分成多個小塊,優先計算含有正樣本的塊的loss ![image](https://hackmd.io/_uploads/S1gbUgxTkx.png) ---- 接著交換資料,直到所有圖文對皆計算完畢 ![image](https://hackmd.io/_uploads/S1aZ8lgTJg.png) --- ## 實驗結果 1. Batch size對 SigLit(Siglip+Vit)影響 2. Siglip vs CLIP 3. mSigLIP:多語言預訓練 4. 使用四個 TPU-v4 晶片訓練SigLiT 5. 使用少量 TPU-v4 晶片預訓練SigLIP 6. 提升參數量 7. 穩定大規模批次訓練 8. Sigmoid loss 中的負樣本比例 9. Bias消融實驗 10. 標籤雜訊寬容度 --- ### 1.Batch size對 SigLit影響 Vit在18B資料集上訓練,batch size 16K前Sigmoid準確度高於softmax,於32K飽和 ![image](https://hackmd.io/_uploads/r1J6bXgTJx.png =350x) --- ### Siglip vs CLIP WebLI資料集上預訓練SigLIP模型,與CLIP比較 SigLIP在32k時表現最佳,而Softmaxloss需要 98k才能收斂 ![image](https://hackmd.io/_uploads/BJs8mQl6Jg.png =350x) --- ### mSigLIP:多語言預訓練 * WebLI資料集上100種語言30B資料量,超過32k會導致性能下降 ![image](https://hackmd.io/_uploads/r16mB7gTyx.png) ---- * 使用「瓶頸」式 embedding,在[詞彙表的大小,嵌入維度]矩陣中引入一個K,K<嵌入維度,表示投影回 W 維的空間 * 將高維度的詞彙表壓縮到一個低維度的「瓶頸」中,然後擴展回原始的維度 * 減少儲存參數量 * 將瓶頸維度 K 設置為 96,相較於使用完整的 250k 詞彙表,在 ImageNet zero-shot 遷移上的效能下降約僅為 0.5% --- ### 使用四個 TPU-v4 晶片訓練SigLiT <font size=4>. | 設定項目 | 第一次實驗 | 第二次實驗 | | -------------- | ----------------------------------------- | ----------------------------------------- | | **視覺塔模型** | **公開可用的 ViT-AugReg-B/8** (**凍結**) | **ViT-g/14** (**凍結**) | | **預計算圖像 Embedding** | **使用與 LiT 相同的方法** | **使用與 LiT 相同的方法** | | **文本塔模型** | **Large Transformer (12 層)** | **Large Transformer (24 層)** | | **優化器** | **LION** | **LION** | | **權重衰減** | **1 × 10⁻⁷ (解耦)** | **1 × 10⁻⁷ (解耦)** | | **學習率排程** | **線性 warm-up (6.5k 步)** 至 **1 × 10⁻⁴**,接續 **餘弦衰減** 至 0 | **線性 warm-up (未明確說明)** 至 **峰值學習率 (未明確說明)**,接續 **餘弦衰減** 至 0 | | **總訓練步數** | **65,000 步** | **107,000 步** | | **批次大小** | **32k** | **20k** | | **訓練天數** | **約一天** | **不到兩天** | | **ImageNet 0-shot 準確率** | **79.7%** | **84.5%** | </font> --- ### 使用少量 TPU-v4 晶片預訓練SigLIP * ViT-AugReg-B/16,在2B大小的 WebLI 英文資料上進行微調,比較直接微調與禁用預訓練權重 ---- 結果:直接微調預訓練模型的效果不佳,但訓練中禁用預訓練權重的 weight decay提升了 SigLIP 的效能 ![image](https://hackmd.io/_uploads/S1Rif4l61l.png) ---- * 改進後,SigLIP 在 16 個 TPU-v4 晶片上以 16k 的批次大小訓練三天,71% 的 ImageNet zero-shot 準確率 * 32 個 TPUv4 晶片上僅用兩天完全訓練就達到了 72.1% 的 ImageNet zero-shot 準確率 ![image](https://hackmd.io/_uploads/HJwTBIxpkl.png) --- ### Sigmoid Loss 中的負樣本比例 * 使用 Sigmoid Loss,容易產生負樣本比例過多的問題,例如,在一個大小為 16k 的批次中,每個正樣本對會對應到 2.68 億個負樣本對 * 通過遮蔽(忽略)足夠的負樣本來模擬不同的「正樣本:負樣本」比例所獲得的分數 ---- * 隨機(Random) * 保留困難負樣本 (Hard):只保留最容易判斷錯誤的負樣本對 * 保留簡單負樣本 (Easy):只保留最容易判斷正確的負樣本對 * 保留困難負樣本並匹配總樣本數 (Hard + matching total pairs seen):確保訓練過程中模型見過的總樣本對數量與不遮蔽的情況相近,增加等比例的訓練的步數 ---- * 隨機:性能下降,減少負樣本的數量不可行 * 保留簡單負樣本:幾乎完全無效 * 保留困難負樣本:幾乎相同,真正有易的資料是負樣本,,比例的不平衡似乎並不是一個主要的性能瓶頸 * 保留困難負樣本並匹配總樣本數:有所提升,效挖掘困難負樣本加強訓練是一個方向 ![image](https://hackmd.io/_uploads/rJe1A0Ue6Jg.png) --- * 穩定大規模批次訓練:較大批次大小訓練不穩定, 調整Adam 和 AdaFactor 的 β2即可改善 * 擴展 SigLIP 和 mSigLIP:透過「過度訓練」模型來擴展的效能, 提高image patches 與64 text tokens數量以提升模型效能 * Bias消融實驗:啟用偏差項並將其初始化為 -10 可以持續改善準確率 * 標籤雜訊寬容度:引入不同類型的雜訊,結果使用Sigmoid loss 訓練的模型抗雜訊能力更強