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