[自然言語処理] [大規模モデル] 大規模言語モデル BLOOM推論ツールテスト

関連ブログ
[ディープラーニング] [分散トレーニング] DeepSpeed: AllReduce と ZeRO-DP
[自然言語処理] [大規模モデル] BLOOM モデル構造のソースコード解析 (スタンドアロン版)
[自然言語処理] [大規模モデル] 非常に低リソース大規模モデル手法の微調整 LoRA および BLOOM-LORA 実装コード
[深層学習] [分散トレーニング] 集団通信操作と Pytorch の例
[自然言語処理] [大規模モデル] チンチラ: 最適なトレーニングとコンピューティング利用を備えた大規模言語モデル
[自然言語]処理] [大規模モデル] 大規模言語モデル BLOOM 推論ツール テスト
[自然言語処理] [大規模モデル] GLM-130B: オープンソースのバイリンガル事前トレーニング済み言語モデル
[自然言語処理] [大規模モデル] 8 ビット行列乗算大型トランスフォーマー入門
【自然言語処理】【大規模モデル】BLOOM: 176Bパラメータとオープンアクセス多言語モデル
【自然言語処理】【ChatGPTシリーズ】FLAN: 言語モデルの微調整はゼロショット学習器
【自然言語処理】 【ChatGPTシリーズ】ChatGPTのインテリジェンスはどこから来るのか?
【自然言語処理】【ChatGPTシリーズ】大規模モデルの登場

BLOOM の原理については、[自然言語処理] [大規模モデル] BLOOM: 176B パラメータとオープンアクセスを備えた多言語モデルを参照してください。

BLOOMはHuggingFace社が発売した大型モデルで、パラメータボリュームは176B(GPT-3は175B)に達します。現時点では、100B を超えるパラメーターを備え、中国語をサポートできるオープンソースの大型モデルは、BLOOM と GLM-130B だけです。HuggingFace は有名なオープンソース ツール Transformers の開発会社であるため、多くの推論ツールが Transformers のモデルをサポートします。

LLM (Large Language Model) 推論に関する 2 つの問題: (1) 1 枚のグラフィックス カードではモデル全体を保持できない; (2) 推論速度が遅すぎる。この記事では、大規模モデルを推論するためのいくつかのツールとコードを事前に整理し、単純に推論速度をテストします。この記事のテストの背景は次のとおりです。

  • 現在2023年2月

  • 7Bモデルbloom-7b1-mtを使用

  • 4 つの 3090 (ただし、実際の推論では 2 つの 3090 のみが使用されます)

  • 依存パッケージのバージョン

    transformers==4.26.0
    tensor-parallel==1.0.24
    deepspeed==0.7.7
    bminf==2.0.1
    

ゼロ、ヘルパー関数

# utils.py
import numpy as np
  
from time import perf_counter

def measure_latency(model, tokenizer, payload, device, generation_args={
    
    }):
    input_ids = tokenizer(payload, return_tensors="pt").input_ids.to(device)
    latencies = []
    # 预热
    for _ in range(2):
        _ =  model.generate(input_ids, **generation_args)
    # 统计时间
    for _ in range(10):
        start_time = perf_counter()
        _ = model.generate(input_ids, **generation_args)
        latency = perf_counter() - start_time
        latencies.append(latency)
    # 计算统计量
    time_avg_ms = 1000 * np.mean(latencies) # 延时均值
    time_std_ms = 1000 * np.std(latencies) # 延时方差
    time_p95_ms = 1000 * np.percentile(latencies,95) # 延时的95分位数
    return f"P95延时 (ms) - {
      
      time_p95_ms}; 平均延时 (ms) - {
      
      time_avg_ms:.2f} +\- {
      
      time_std_ms:.2f};"

def infer(model, tokenizer, payload, device):
    input_ids = tokenizer(payload, return_tensors="pt").input_ids.to(device)
    logits = model.generate(input_ids, num_beams=1, max_length=512)
    out = tokenizer.decode(logits[0].tolist())
    return out

1. 層の並列性

BLOOM は Huggingface によって開発されているため、トランスフォーマー ライブラリでのサポートを提供します。具体的には、from_pretrained読み込んだモデルを使用する場合にパラメータを指定しますdevce_mapモデルの異なるレイヤーを異なるグラフィックス カードに配置することで、単一の大きなモデルを複数のカードに分割します (並列パイプラインもレイヤーを分割し、パイプライン方式でモデルをトレーニングします)呼び出しのサンプルコードは次のとおりです。

# layer_parallel_test.py
import os
import transformers

from utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLM

transformers.logging.set_verbosity_error()
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1"

def run():
    model_name = "bigscience/bloomz-7b1-mt"
    payload = """
    参考下面的文章,然后用与文章相同的语言回答问题: 段落:当细菌突破免疫系统的防御而开始增生时,疾病会由结核菌感染进展到症状明显的结核病。在原发型结核病 (占 1-5% 的比例),这种现象会在感染刚开始的时候很快的发生。然而>多数人感染模式为潜伏结核感染,通常没有明显症状。在5-10%潜伏结合感染的案例中,这些休眠的细菌经常会在感染后数年的时间制造出活动的结核。 问题:What is the next stage after TB infection?
    """
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto")
    model = model.eval()
    out = infer(model, tokenizer, payload, model.device)
    print("="*70+" 模型输入输出 "+"="*70)
    print(f"模型输入: {
      
      payload}")
    print(f"模型输出: {
      
      out}")
    print("\n\n"+"="*70+" 模型延时测试 "+"="*70)
    print(measure_latency(model, tokenizer, payload, model.device))
    print("\n\n"+"="*70+" 显存占用 "+"="*70)
    print(os.system("nvidia-smi"))

if __name__ == "__main__":
    run()
    pass

モデルの遅延結果は次のようになります。

P95 遅延 (ミリ秒) - 118.402308691293; 平均遅延 (ミリ秒) - 117.72 +- 0.58;

メモリ使用量:

画像の説明を追加してください

2. テンソル並列処理

テンソル並列処理は行列の乗算をブロックに分割し、それによって大きな行列を小さな行列に分割し、異なる行列を異なるグラフィックス カードに配置できるようにします。(具体的な原則については次回以降の記事で紹介します)

これは、オープンソース ツールキット tensor_Parallel を使用して実現されます。

# tensor_parallel_test.py
import os
import transformers
import tensor_parallel as tp

from utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLM

transformers.logging.set_verbosity_error()
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1"

def run():
    model_name = "bigscience/bloomz-7b1-mt"
    payload = """
    参考下面的文章,然后用与文章相同的语言回答问题: 段落:当细菌突破免疫系统的防御而开始增生时,疾病会由结核菌感染进展到症状明显的结核病。在原发型结核病 (占 1-5% 的比例),这种现象会在感染刚开始的时候很快的发生。然而>多数人感染模式为潜伏结核感染,通常没有明显症状。在5-10%潜伏结合感染的案例中,这些休眠的细菌经常会在感染后数年的时间制造出活动的结核。 问题:What is the next stage after TB infection?
    """
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    model = AutoModelForCausalLM.from_pretrained(model_name, low_cpu_mem_usage=True)
    model = tp.tensor_parallel(model, ["cuda:0", "cuda:1"])
    model = model.eval()
    out = infer(model, tokenizer, payload, model.device)
    print("="*70+" 模型输入输出 "+"="*70)
    print(f"模型输入: {
      
      payload}")
    print(f"模型输出: {
      
      out}")
    print("\n\n"+"="*70+" 模型延时测试 "+"="*70)
    print(measure_latency(model, tokenizer, payload, model.device))
    print("\n\n"+"="*70+" 显存占用 "+"="*70)
    print(os.system("nvidia-smi"))

if __name__ == "__main__":
    run()
    pass

モデルの遅延結果は次のようになります。

P95 遅延 (ms) - 91.34029923006892; 平均遅延 (ms) - 90.66 +- 0.46;

メモリ使用量:

画像の説明を追加してください

3. モデルの定量化

原理については、[自然言語処理] [大規模モデル] 大規模な Transformers のための 8 ビット行列乗算の概要 を参照してください。

量子化は一般的なモデル圧縮手法であり、中心的な考え方は、モデル パラメーターを高精度から低精度に変換することです。BLOOM で 8 ビット量子化を使用するには、を呼び出すfrom_pretrainedときにパラメータを設定するだけで済みますload_in_8bit=True, device_map="auto"

(注: ブルームが量子化を実装すると、しきい値を超えるかどうかに応じて行列が分割され、しきい値を下回るモデル パラメーターが量子化されるため、推論速度が遅くなります)

# int8_test.py
import os
import transformers

from utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLM

transformers.logging.set_verbosity_error()
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1"

def run():
    model_name = "bigscience/bloomz-7b1-mt"
    payload = """
    参考下面的文章,然后用与文章相同的语言回答问题: 段落:当细菌突破免疫系统的防御而开始增生时,疾病会由结核菌感染进展到症状明显的结核病。在原发型结核病 (占 1-5% 的比例),这种现象会在感染刚开始的时候很快的发生。然而>多数人感染模式为潜伏结核感染,通常没有明显症状。在5-10%潜伏结合感染的案例中,这些休眠的细菌经常会在感染后数年的时间制造出活动的结核。 问题:What is the next stage after TB infection?
    """
    max_memory_mapping = {
    
    0: "24GB", 1: "0GB"}
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    model = AutoModelForCausalLM.from_pretrained(model_name, load_in_8bit=True, device_map="auto", max_memory=max_memory_mapping)
    model = model.eval()
    out = infer(model, tokenizer, payload, model.device)
    print("="*70+" 模型输入输出 "+"="*70)
    print(f"模型输入: {
      
      payload}")
    print(f"模型输出: {
      
      out}")
    print("\n\n"+"="*70+" 模型延时测试 "+"="*70)
    print(measure_latency(model, tokenizer, payload, model.device))
    print("\n\n"+"="*70+" 显存占用 "+"="*70)
    print(os.system("nvidia-smi"))

if __name__ == "__main__":
    run()
    pass

モデルの遅延結果は次のようになります。

P95 遅延 (ミリ秒) - 147.89210632443428; 平均遅延 (ミリ秒) - 143.30 +- 3.02;

メモリ使用量:

画像の説明を追加してください

四、DeepSpeed推論

DeepSpeed-Inference は、分散トレーニング ツール DeepSpeed のユーザー モデル推論の機能です。

# deepspeed_test.py
import os
import torch
import deepspeed
import transformers

from utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLM

transformers.logging.set_verbosity_error()
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1"

def run():
    model_name = "bigscience/bloomz-7b1-mt"
    payload = """
    参考下面的文章,然后用与文章相同的语言回答问题: 段落:当细菌突破免疫系统的防御而开始增生时,疾病会由结核菌感染进展到症状明显的结核病。在原发型结核病 (占 1-5% 的比例),这种现象会在感染刚开始的时候很快的发生。然而>多数人感染模式为潜伏结核感染,通常没有明显症状。在5-10%潜伏结合感染的案例中,这些休眠的细菌经常会在感染后数年的时间制造出活动的结核。 问题:What is the next stage after TB infection?
    """
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16)
    model = deepspeed.init_inference(
            model=model,      # Transformers模型
            mp_size=2,        # 模型并行数量
            dtype=torch.float16, # 权重类型(fp16)
            replace_method="auto", # 让DS自动替换层
            replace_with_kernel_inject=True, # 使用kernel injector替换
            )
    out = infer(model, tokenizer, payload, model.module.device)
    print("="*70+" 模型输入输出 "+"="*70)
    print(f"模型输入: {
      
      payload}")
    print(f"模型输出: {
      
      out}")
    print("\n\n"+"="*70+" 模型延时测试 "+"="*70)
    print(measure_latency(model, tokenizer, payload, model.module.device))
    print("\n\n"+"="*70+" 显存占用 "+"="*70)
    print(os.system("nvidia-smi"))


if __name__ == "__main__":
    run()
    pass

ここでは Python を使用してスクリプトを自動化することはできません。次のコマンドを使用する必要があります。

deepspeed --num_gpus 2 --master_port 60000 deepspeed_test.py

モデルの遅延結果は次のようになります。

P95 遅延 (ミリ秒) - 31.88958093523979; 平均遅延 (ミリ秒) - 30.75 +- 0.64;

メモリ使用量:

画像の説明を追加してください

5.BMInf

BMInf は単一のグラフィックス カードで完全なモデルをロードできますが、推論速度が非常に遅くなります (オフロード テクノロジを使用する必要があります)。

import os
import bminf
import transformers

from utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLM

transformers.logging.set_verbosity_error()
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1"

def run():
    model_name = "bigscience/bloomz-7b1-mt"
    payload = """
    参考下面的文章,然后用与文章相同的语言回答问题: 段落:当细菌突破免疫系统的防御而开始增生时,疾病会由结核菌感染进展到症状明显的结核病。在原发型结核病 (占 1-5% 的比例),这种现象会在感染刚开始的时候很快的发生。然而>多数人感染模式为潜伏结核感染,通常没有明显症状。在5-10%潜伏结合感染的案例中,这些休眠的细菌经常会在感染后数年的时间制造出活动的结核。 问题:What is the next stage after TB infection?
    """
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    model = AutoModelForCausalLM.from_pretrained(model_name, low_cpu_mem_usage=True)
    model = model.eval()
    model = bminf.wrapper(model, quantization=False, memory_limit=8 << 30)
    out = infer(model, tokenizer, payload, model.device)
    print("="*70+" 模型输入输出 "+"="*70)
    print(f"模型输入: {
      
      payload}")
    print(f"模型输出: {
      
      out}")
    print("\n\n"+"="*70+" 模型延时测试 "+"="*70)
    print(measure_latency(model, tokenizer, payload, model.device))
    print("\n\n"+"="*70+" 显存占用 "+"="*70)
    print(os.system("nvidia-smi"))

if __name__ == "__main__":
    run()
    pass

モデルの遅延結果は次のようになります。

P95 遅延 (ミリ秒) - 719.2403690889478; 平均遅延 (ミリ秒) - 719.05 +- 0.14;

メモリ使用量:

画像の説明を追加してください

6. 結論

  • DeepSpeed-Inference の速度は最速です。
  • テンソル並列処理は、組み込みレイヤー並列処理よりも高速です。
  • 8 ビット量子化の速度は遅くなりますが、シングルカード推論を実現できます。
  • BMInf は最も遅いですが、モデルの精度を損なうことなくシングルカード推論を実行できます。

説明する

  • この記事は、これらの推論ツールのベスト プラクティスではなく、これらのツールがどのように使用されるかをリストして示しているだけです。
  • これらのツールは、さまざまな観点からモデル推論を最適化します。実装方法について詳しく知りたい場合は、ソース コードを読むことができます。

おすすめ

転載: blog.csdn.net/bqw18744018044/article/details/129351831