多模態理解SOTA模型開箱即用,MindSpeedMM支援Qwen2.5-VL最佳實踐

多模態理解模型是讓AI像人類一樣,透過整合多維度資訊(如視覺、語言、聽覺等),理解資料背後的語義、情感、邏輯或場景,從而完成推理、決策等任務。
當前已經進入多模態理解大模型發展的快車道,2025年2月,最新一代的多模態理解模型Qwen2.5VL開源釋出,其在多個基準測試中取得了SOTA效果,更是直接登頂司南(OpenCompass)排行榜,甚至超越國內外知名的GPT-4o和Gemini-2.0等閉源模型。
MindSpeed MM開發團隊快速對Qwen2.5VL模型全系列尺寸進行適配,並將其正式開源在MindSpeed MM倉庫,同時支援檢視理解全參微調訓練、Lora微調訓練、線上推理和評測。
MindSpeed MM基於MindSpeed Core的多維並行能力實現對多模態模型的極致效能最佳化,更親和昇騰硬體,致力成為昇騰開發者大叢集、大引數場景多模態訓練的首選,為開發者提供高效易用的開發體驗。
基於MindSpeed MM的

Qwen2.5VL檢視理解生成體驗

新一代的多模態理解模型Qwen2.5VL有強大的檢視理解能力,讓我們快速體驗一下。
  • 圖片理解體驗:
  • Prompt請描述這張圖片
  • 輸出結果:

  • 影片理解體驗:
影片畫面由AI輔助生成
  • Prompt請描述這個影片。
  • 輸出結果:
基於MindSpeed MM的
Qwen2.5VL訓練最佳化特性
多模態理解模型主要處理如文字、影像、音訊、影片、感測器訊號等模態資料,不同模態資料存在結構差異、特徵表示異質性、融合策略多樣性、訓練機制複雜性等特點,Qwen2.5VL訓練的效能瓶頸主要是負載不均衡問題。MindSpeed MM在使用融合運算元、分散式最佳化器及流水排程最佳化等常用特性的基礎上,支援多模態異構流水線並行、動態流水線並行、資料分桶負載均衡等最佳化加速特性,實現訓練效能極致最佳化。
01
多模態異構流水線並行,支援大規模資料的複雜多模態訓練,實現負載均衡
Qwen2.5VL模型包括視覺模組、連線層以及語言模組,其中視覺模組的啟用值比較大,當視覺模組放開訓練或檢視資料規模較大時,會導致視訊記憶體佔用過大甚至OOM,同時影響多卡之間的負載均衡。MindSpeed MM創新性地實現了異構流水線並行特性,支援各種模態模組的快速流水線並行適配,支撐實現更復雜場景和更大資料規模的訓練微調,同時也緩解了負載不均衡的問題。

使用方式:在examples/qwen2.5vl/model_*b.json中配置vision_encoder和text_decoder中的pipeline_num_layers欄位引數

02
流水線並行動態shape通訊支援,實現訓練效率和資源利用率雙提升
多模態場景中,batch內樣本長度要保持一致,需將所有輸入樣本都擴充套件到統一的序列長度,而不同樣本的序列長度差異較大,對於短序列的資料樣本會產生大量冗餘計算、增加視訊記憶體佔用和通訊耗時。MindSpeed MM透過使用MindSpeed Core的動態shape流水線並行特性,減少過度擴充套件現象,有效降低冗餘計算量,實現訓練效率與計算資源利用率雙提升,資料集序列長度差異越大,收益越大。 

使用方式:在examples/qwen2.5vl/finetune_qwen2_5_vl_*b.sh的GPT_ARGS中加入–variable-seq-lengths引數。

03
資料分桶負載最佳化,實現多卡資料計算均衡,訓練效率提升10%+
多模態理解場景由於檢視資料的規模不一致,不同輸入資料長度差異很大,因此會導致大叢集訓練微調過程中,不同卡之間的計算耗時差異大,出現卡間負載不均衡問題。MindSpeed MM中透過實現全域性資料分桶重排,將不同序列長度的資料重新進行劃分,從而實現卡間的資料大小基本相同,保證訓練資料多樣性的同時訓練效率提升10%+。

資料分桶負載:將資料按token數量
分配到不同的桶,訓練時按桶取資料

使用方式:在examples/qwen2.5vl/data_*b.json中,修改dataloader_param下的sampler_type為"BucketBatchSampler"

快速上手

基於MindSpeed MM

玩轉Qwen2.5VL

環境安裝
模型開發時推薦使用配套的環境版本,詳見倉庫中的”環境安裝”
https://gitee.com/ascend/MindSpeed-MM/blob/master/examples/qwen2.5vl/README.md
倉庫拉取:
git clone https://gitee.com/ascend/MindSpeed-MM.git
git clone https://github.com/NVIDIA/Megatron-LM.git
cd Megatron-LM
git checkout core_r0.8.0
cp -r megatron ../MindSpeed-MM/
cd ..
cd MindSpeed-MM
mkdir logs
mkdir data
mkdir ckpt
環境搭建:
torch npu 與 CANN包參考連結:安裝包參考連結
https://gitee.com/link?target=https%3A%2F%2Fsupport.huawei.com%2Fenterprise%2Fzh%2Fascend-computing%2Fcann-pid-251168373%2Fsoftware
# python3.10
conda create -n test python=3.10
conda activate test
安裝 torch  torch_npu,注意要選擇對應python版本、x86armtorchtorch_npuapex
下載路徑參考 https://www.hiascend.com/document/detail/zh/Pytorch/60RC3/configandinstg/instg/insg_0001.html
pip install torch-2.1.0-cp310-cp310m-manylinux2014_aarch64.whl
pip install torch_npu-2.1.0*-cp310-cp310m-linux_aarch64.whl
# apex for Ascend 參考 https://gitee.com/ascend/apex
建議從原倉編譯安裝
安裝加速庫
git clone https://gitee.com/ascend/MindSpeed.git
cd MindSpeed
# checkout commit from MindSpeed core_r0.8.0
git checkout 3f09d6736571cf1e30f8ac97de77982d0ab32cc5
pip install -r requirements.txt
pip3 install -e .
cd ..
替換MindSpeed中的檔案
cp examples/qwen2vl/dot_product_attention.py MindSpeed/mindspeed/core/transformer/dot_product_attention.py
安裝其餘依賴庫
pip install -e .
安裝transformers指定版本
git clone https://github.com/huggingface/transformers.git
cd transformers
git checkout fa56dcc2a
pip install -e .
權重下載及轉換
Qwen2.5VL權重下載:
模型
Huggingface下載連結
3B
https://huggingface.co/Qwen/Qwen2.5-VL-3B-Instruct/tree/main
7B
https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct/tree/main
32B
https://huggingface.co/Qwen/Qwen2.5-VL-32B-Instruct/tree/main
72B
https://huggingface.co/Qwen/Qwen2.5-VL-72B-Instruct/tree/main
權重轉換:
MindSpeed MM修改了部分原始網路的結構名稱,使用mm-convert工具對原始預訓練權重進行轉換。該工具實現了huggingface權重和MindSpeed MM權重的互相轉換以及PP(Pipeline Parallel)權重的重切分。
# 3b
mm-convert  Qwen2_5_VLConverter hf_to_mm \
  --cfg.mm_dir "ckpt/mm_path/Qwen2.5-VL-3B-Instruct" \
  --cfg.hf_config.hf_dir "ckpt/hf_path/Qwen2.5-VL-3B-Instruct" \
  --cfg.parallel_config.llm_pp_layers [36] \
  --cfg.parallel_config.vit_pp_layers [32] \
  --cfg.parallel_config.tp_size 1
# 7b
mm-convert  Qwen2_5_VLConverter hf_to_mm \
  --cfg.mm_dir "ckpt/mm_path/Qwen2.5-VL-7B-Instruct" \
  --cfg.hf_config.hf_dir "ckpt/hf_path/Qwen2.5-VL-7B-Instruct" \
  --cfg.parallel_config.llm_pp_layers [1,10,10,7] \
  --cfg.parallel_config.vit_pp_layers [32,0,0,0] \
  --cfg.parallel_config.tp_size 1
# 32b
mm-convert  Qwen2_5_VLConverter hf_to_mm \
  --cfg.mm_dir "ckpt/mm_path/Qwen2.5-VL-32B-Instruct" \
  --cfg.hf_config.hf_dir "ckpt/hf_path/Qwen2.5-VL-32B-Instruct" \
  --cfg.parallel_config.llm_pp_layers [4,9,9,9,9,9,9,6] \
  --cfg.parallel_config.vit_pp_layers [32,0,0,0,0,0,0,0] \
  --cfg.parallel_config.tp_size 2
# 72b
mm-convert  Qwen2_5_VLConverter hf_to_mm \
  --cfg.mm_dir "ckpt/mm_path/Qwen2.5-VL-72B-Instruct" \
  --cfg.hf_config.hf_dir "ckpt/hf_path/Qwen2.5-VL-72B-Instruct" \
  --cfg.parallel_config.llm_pp_layers [14,23,23,20] \
  --cfg.parallel_config.vit_pp_layers [32,0,0,0] \
  --cfg.parallel_config.tp_size 8
其中:
# mm_dir: 轉換後儲存目錄
# hf_dir: huggingface權重目錄
# llm_pp_layers: llm在每個卡上切分的層數,注意要和model.json中配置的pipeline_num_layers一致
# vit_pp_layers: vit在每個卡上切分的層數,注意要和model.json中配置的pipeline_num_layers一致
# tp_size: tp並行數量,注意要和微調啟動指令碼中的配置一致
如果需要用轉換後模型訓練的話,同步修改
examples/qwen2.5vl/finetune_qwen2_5_vl_7b.sh中的LOAD_PATH引數,該路徑為轉換後或者切分後的權重,注意與原始權重ckpt/hf_path/Qwen2.5-VL-7B-Instruct進行區分。
LOAD_PATH="ckpt/mm_path/Qwen2.5-VL-7B-Instruct"
【資料集準備及處理】
資料集下載(coco2017資料集為例)
(1)使用者需要自行下載COCO2017資料集,並解壓到專案目錄下的./data/COCO2017資料夾中
下載連結:https://gitee.com/link?target=https%3A%2F%2Fcocodataset.org%2F%23download
(2)獲取圖片資料集的描述檔案(LLaVA-Instruct-150K),下載至./data/路徑下;
https://gitee.com/link?target=https%3A%2F%2Fhuggingface.co%2Fdatasets%2Fliuhaotian%2FLLaVA-Instruct-150K%2Ftree%2Fmain

(3)在./data路徑下新建檔案mllm_format_llava_instruct_data.json,執行資料轉換指令碼python examples/qwen2vl/llava_instruct_2_mllm_demo_format.py;

$playground
├── data
    ├── COCO2017
        ├── train2017
    ├── llava_instruct_150k.json
    ├── mllm_format_llava_instruct_data.json
    ...
當前支援讀取多個以,(注意不要加空格)分隔的資料集,配置方式為data.json中 dataset_param->basic_parameters->dataset 從"./data/mllm_format_llava_instruct_data.json"修改為"./data/mllm_format_llava_instruct_data.json,./data/mllm_format_llava_instruct_data2.json"
同時注意data.json中dataset_param->basic_parameters->max_samples的配置,會限制資料只讀max_samples條,這樣可以快速驗證功能。如果正式訓練時,可以把該引數去掉則讀取全部的資料。
純文字或有圖無圖混合訓練資料(以LLaVA-Instruct-150K為例):

現在本框架已經支援純文字/混合資料(有影像和無影像資料混合訓練)。在資料構造時,對於包含圖片的資料,需要保留image這個鍵值。

{
"id": your_id,
"image": your_image_path,
"conversations": [
      {"from""human""value": your_query},
      {"from""gpt""value": your_response},
  ],
}

在資料構造時,對於純文字資料,可以去除image這個鍵值。

{
"id": your_id,
"conversations": [
      {"from""human""value": your_query},
      {"from""gpt""value": your_response},
  ],
}
【微調】
1. 準備工作
配置指令碼前需要完成前置準備工作,包括:環境安裝、權重下載及轉換、資料集準備及處理,詳情可檢視對應章節。
2. 配置引數

資料目錄配置:

根據實際情況修改data.json中的資料集路徑,包括model_name_or_path、dataset_dir、dataset等欄位。
以Qwen2.5VL-7B為例,data.json進行以下修改,注意model_name_or_path的權重路徑為轉換前的權重路徑。

注意cache_dir在多機上不要配置同一個掛載目錄避免寫入同一個檔案導致衝突。

{
    "dataset_param": {
        "dataset_type": "huggingface",
        "preprocess_parameters": {
            "model_name_or_path": "./ckpt/hf_path/Qwen2.5-VL-7B-Instruct",
            ...
        },
        "basic_parameters": {
            ...
            "dataset_dir": "./data",
            "dataset": "./data/mllm_format_llava_instruct_data.json",
            "cache_dir": "./data/cache_dir",
            ...
        },
        ...
    },
    ...
    }
}
模型儲存載入及日誌資訊配置:
根據實際情況配置examples/qwen2.5vl/finetune_qwen2_5_vl_7b.sh的引數,包括載入、儲存路徑以及儲存間隔–save-interval(注意:分散式最佳化器儲存檔案較大耗時較長,請謹慎設定儲存間隔)
...
#載入路徑
LOAD_PATH="ckpt/mm_path/Qwen2.5-VL-7B-Instruct"
#儲存路徑
SAVE_PATH="save_dir"
...
GPT_ARGS="
    ...
    --no-load-optim \  # 不載入最佳化器狀態,若需載入請移除
    --no-load-rng \  # 不載入隨機數狀態,若需載入請移除
    --no-save-optim \  # 不儲存最佳化器狀態,若需儲存請移除
    --no-save-rng \  # 不儲存隨機數狀態,若需儲存請移除
    ...
"
...
OUTPUT_ARGS="
    --log-interval 1 \  # 日誌間隔
    --save-interval 5000 \  # 儲存間隔
    ...
    --log-tps \  # 增加此引數可使能在訓練中列印每步語言模組的平均序列長度,並在訓練結束後計算每秒吞吐tokens量。
"
若需要載入指定迭代次數的權重、最佳化器等狀態,需將載入路徑LOAD_PATH設定為儲存資料夾路徑LOAD_PATH="save_dir",並修改latest_checkpointed_iteration.txt檔案內容為指定迭代次數 (此功能coming soon)
$save_dir
   ├── latest_checkpointed_iteration.txt
   ├── ...
單機執行配置:

配置examples/qwen2.5vl/finetune_qwen2_5_vl_7b.sh引數如下

#根據實際情況修改 ascend-toolkit 路徑
source /usr/local/Ascend/ascend-toolkit/set_env.sh
NPUS_PER_NODE=8
MASTER_ADDR=locahost
MASTER_PORT=29501
NNODES=1
NODE_RANK=0
WORLD_SIZE=$(($NPUS_PER_NODE * $NNODES))
注意,當開啟PP時,model.json中配置的vision_encoder和text_decoder的pipeline_num_layer引數控制了各自的PP切分策略。對於流水線並行,要先處理vision_encoder再處理text_decoder。 比如7b預設的值[32,0,0,0]、[1,10,10,7],其含義為PP域內第一張卡先放32層vision_encoder再放1層text_decoder、第二張卡放text_decoder接著的10層、第三張卡放text_decoder接著的10層、第四張卡放text_decoder接著的7層,vision_encoder沒有放完時不能先放text_decoder(比如[30,2,0,0]、[1,10,10,7]的配置是錯的)。
同時注意,如果某張卡上的引數全部凍結時會導致沒有梯度(比如vision_encoder凍結時PP配置[30,2,0,0]、[0,11,10,7]),需要在finetune_qwen2_5_vl_7b.sh中GPT_ARGS引數中增加–enable-dummy-optimizer,
3. 啟動微調
以Qwen2.5VL-7B為例,啟動微調訓練任務。
bash examples/qwen2.5vl/finetune_qwen2_5_vl_7b.sh
【效能實測:昇騰硬體加速提升效能】
備註:Samples per Second 為 (SPS)
模型尺寸
任務型別
訓練規模(A2)
混精型別
效能
3B
微調
單機8卡
bf16
23.771(SPS)
7B
微調
單機8卡
bf16
14.204(SPS)
32B
微調
雙機16卡
bf16
6.755(SPS)
72B
微調
4機32卡
bf16
4.669(SPS)
【更多引數見MindSpeed MM倉庫】
準備工作和引數說明見MindSpeed MM開原始碼倉連結: 
https://gitee.com/ascend/MindSpeed-MM/tree/master/examples/qwen2.5vl
結語
MindSpeed MM是面向大規模分散式訓練的昇騰多模態大模型套件,同時支援多模態生成及多模態理解,旨在為華為昇騰晶片提供端到端的多模態訓練解決方案, 包含預置業界主流模型,資料工程,分散式訓練及加速,預訓練、微調、線上推理任務等特性。
MindSpeed MM即將上線更加豐富的支援Qwen2.5VL模型的特性,敬請期待。
歡迎關注MindSpeed MM:https://gitee.com/ascend/MindSpeed-MM


相關文章