[自然言語処理] [分散トレーニングと推論] 推論ツール DeepSpeed-Inference

関連ブログ
[ディープラーニング] [分散トレーニング] 集団通信操作とPytorchの例
[自然言語処理] [分散トレーニングと推論] 推論ツール DeepSpeed-Inference
[自然言語処理] [chatGPTシリーズ] 大規模な言語モデルは自らを改善できる
[ 自然言語Processing] [ChatGPT シリーズ] WebGPT: 人間のフィードバックに基づくブラウザ支援 Q&A
[自然言語処理] [ChatGPT シリーズ] FLAN: 言語モデルの微調整はゼロショット学習者
[自然言語処理] [ChatGPT シリーズ] ChatGPT どこから?
[自然言語処理] [ChatGPT シリーズ] 思考連鎖: 大規模モデルから推論能力を誘導する
[自然言語処理] [ChatGPT シリーズ] InstructGPT: 人間のフィードバック命令に従って言語モデルをトレーニングする
[自然言語処理] [ChatGPT シリーズ]モデル

推論ツール DeepSpeed-Inference

DeepSpeed-Inference は、推論の観点から DeepSpeed フレームワークを拡張したものです。DeepSpeed-Inference には、テンソル、パイプライン並列処理、カスタム最適化された cuda コアなどの並列化テクノロジが組み込まれています。DeepSpeed は、DeepSpeed、Megatron、および HuggingFace によってトレーニングされた Transformer モデルと互換性のあるシームレスな推論モードを提供します。DeepSpeed-Inference はモデル並列テクノロジーを統合しているため、大規模なモデル推論を複数の GPU で実行できます。

この記事では、HuggingFace の BLOOM モデルを例として、DeepSpeed-Inference の使用方法を示します。

import os
import torch
import deepspeed
import numpy as np
import transformers

from time import perf_counter
from transformers import AutoTokenizer, AutoModelForCausalLM
from deepspeed.ops.transformer.inference import DeepSpeedTransformerInference

transformers.logging.set_verbosity_error()

1. 直接推論

最初に 7B モデルをロードします

model_name = "bigscience/bloomz-7b1-mt"
payload = "一个传奇的开端,一个不灭的神话,这不仅仅是一部电影,而是作为一个走进新时代的标签,永远彪炳史册。你认为这句话的立场是赞扬、中立还是批评?"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16, device_map="auto")
print(f"模型加载至设备{
      
      model.device.type}")

推論関数を定義し、推論を試みます

def inference(payload, model, tokenizer):
    input_ids = tokenizer(payload, return_tensors="pt").input_ids.to(model.device)
    print(f"输入:\n    {
      
      payload}")
    logits = model.generate(input_ids, do_sample=True, num_beams=1, max_new_tokens=128)
    print(f"生成:\n    {
      
      tokenizer.decode(logits[0].tolist()[len(input_ids[0]):])}")
    
if __name__ == "__main__":
    inference(payload, model, tokenizer)
# 执行结果
"""
输入:
    一个传奇的开端,一个不灭的神话,这不仅仅是一部电影,而是作为一个走进新时代的标签,永远彪炳史册。你认为这句话的立场是赞扬、中立还是批评?
生成:
     赞扬</s>
"""

レイテンシを測定する関数を定義する

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 latency (ms) - {
      
      time_p95_ms}; Average latency (ms) - {
      
      time_avg_ms:.2f} +\- {
      
      time_std_ms:.2f};", time_p95_ms

def test_inference_time():
    print(f'输入序列的长度为: {
      
      len(tokenizer(payload)["input_ids"])}')
    generation_args = dict(
            do_sample=False,
            num_beams=1,
            max_new_tokens=128)
    vanilla_results = measure_latency(model, tokenizer, payload, model.device, generation_args)
    print(f"普通模型的结果: {
      
      vanilla_results[0]}")
    
if __name__ == "__main__":
    test_inference_time()
# 执行结果
"""
普通模型的结果: P95 latency (ms) - 147.3398147150874; Average latency (ms) - 143.50 +\- 2.45;
"""

二、DeepSpeed-Inference

DeepSpeed-Inference は、テンソル並列処理を通じて大規模なモデルを複数のカードに分解することができ、それによって推論を完了し、一定の高速化を実現します。

7Bのモデルをロード

model_name = "bigscience/bloomz-7b1-mt"
payload = "一个传奇的开端,一个不灭的神话,这不仅仅是一部电影,而是作为一个走进新时代的标签,永远彪炳史册。你认为这句话的立场是赞扬、中立还是批评?"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16)

ds_model = deepspeed.init_inference(
    model=model,      # Transformers模型
    mp_size=4,        # GPU数量
    dtype=torch.float16, # 权重类型(fp16)
    replace_method="auto", # 让DS自动替换层
    replace_with_kernel_inject=True, # 使用kernel injector替换
)
print(f"模型加载至设备{
      
      ds_model.module.device}\n")
assert isinstance(ds_model.module.transformer.h[0], DeepSpeedTransformerInference) == True, "Model not sucessfully initalized"

レイテンシを測定する関数を定義する

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"DeepSpeed模型的结果: P95 latency (ms) - {
      
      time_p95_ms}; Average latency (ms) - {
      
      time_avg_ms:.2f} +\- {
      
      time_std_ms:.2f};", time_p95_ms

推論タスクを実行し、レイテンシを測定する

def test_inference():
    # 执行模型推理
    input_ids = tokenizer(payload, return_tensors="pt").input_ids.to(model.device)
    logits = ds_model.generate(input_ids, do_sample=True, max_length=100)
    print(tokenizer.decode(logits[0].tolist()))

def test_inference_time():
    # 衡量推理时延
    print(f'输入序列的长度为: {
      
      len(tokenizer(payload)["input_ids"])}')
    generation_args = dict(do_sample=False, num_beams=1, max_new_tokens=128)
    ds_results = measure_latency(ds_model, tokenizer, payload, ds_model.module.device, generation_args)
    print(f"DeepSpeed model: {
      
      ds_results[0]}")

if __name__ == "__main__":
    test_inference()
    test_inference_time()
# 执行结果
"""
DeepSpeed model: DeepSpeed模型的结果: P95 latency (ms) - 80.4762739688158; Average latency (ms) - 77.79 +\- 2.20;
"""

DeepSpeedのコードはPythonでは実行できません。deepspeedコマンドで実行する必要があります。例は次のとおりです

# bloom_ds_inference.py就是需要执行的python脚本
deepspeed --num_gpus 4 --master_port 60000 bloom_ds_inference.py

3. 結果

この実験では 4 3090 を使用します。

  • DeepSpeed-Inference を使用する前の平均遅延は 143.5 ミリ秒、使用後は 77.79 ミリ秒です。全体として、速度は1.84 倍向上しました。
  • DeepSpeed-Inference を使用すると、単一のモデルを複数の GPU に割り当てることができ、単一の GPU にロードできないモデルについては、複数の GPU を推論に使用できます。

参考文献

GPU 上の DeepSpeed-Inference を使用して GPT-J 推論を高速化する

Transformer ベースのモデルを推論するための DeepSpeed 入門

おすすめ

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