バイトダンスモデル大規模展開実戦

王林
リリース: 2023-04-12 20:31:04
転載
1121 人が閲覧しました

バイトダンスモデル大規模展開実戦

1. 背景の紹介

ByteDance では、ディープラーニングをベースにしたアプリケーションが随所で開花しており、エンジニアはモデルの効果に注目する一方で、オンライン サービスにも注意を払う必要があります一貫性とパフォーマンス。初期の頃、これには通常、アルゴリズムの専門家とエンジニアリングの専門家の間の分業と密接な協力が必要でした。このモデルには、差分トラブルシューティングや検証などの比較的高いコストがかかります。

PyTorch/TensorFlow フレームワークの人気により、深層学習モデルのトレーニングとオンライン推論が統合されました。開発者は、特定のアルゴリズム ロジックに注意を払い、フレームワークの Python API を呼び出すだけでトレーニングを完了できます。その後、モデルをシリアル化してエクスポートするのが非常に便利で、推論作業は統合された高性能 C エンジンによって完了します。トレーニングから展開までの開発者のエクスペリエンスが向上します。

ただし、完成したサービスには通常、前処理/後処理などの多くのビジネス ロジックが含まれており、このタイプのロジックでは通常、さまざまな入力を処理して Tensor に変換し、モデルに入力します。 、モデル出力 Tensor はターゲット形式に処理されます。いくつかの典型的なシナリオは次のとおりです。

  • ##私たちの目標は、上記のエンドツーエンドのプロセスに自動化および統合されたトレーニングと推論ソリューションを提供し、推論プロセスの手動開発などの一連の問題を軽減することです。とアライメントの差分を分析し、大規模な統合導入ソリューションを実現します。
  • 2. 主要な問題

PyTorch/TensorFlow などのフレームワークは、統合されたモデルのトレーニング/推論の問題を比較的解決しているため、モデルの計算自体にはトレーニングと推論の統合という問題はありません (オペレータのパフォーマンスの最適化については、この説明の範囲外です)。 バイトダンスモデル大規模展開実戦

解決すべき中心的な問題は、前処理と後処理で高パフォーマンスのトレーニングを提供し、統合ソリューションを推進する必要があるということです。

バイトダンスモデル大規模展開実戦このタイプのロジックの場合、TensorFlow 2.x は tf.function (まだ完成していません) を提供し、PyTorch は例外なくネイティブ Python 構文のサブセットを選択する TorchScript を提供します。しかし、たとえ非常に強力であっても、依然として無視できない問題があります:

パフォーマンス: このソリューションのほとんどは仮想マシンの実装に基づいています。仮想マシン ソリューションは柔軟性があり、非常に制御可能ですが、深層学習フレームワークのほとんどの仮想マシンは通常、パフォーマンスが十分ではありません。補足すると、このフレームワークは初期の Tensor コンピューティング向けに設計されたものであり、配列コンピューティングにおける各オペレーターのコストは非常に高く、仮想マシンのディスパッチやスケジューリングのコストは無視できます。ただし、プログラミング言語プログラミングへの移植のオーバーヘッドは無視するのが難しく、コードを書きすぎるとパフォーマンスのボトルネックになります。テストによると、TorchScript インタプリタのパフォーマンスは Python のパフォーマンスの約 1/5 にすぎず、tf.function のパフォーマンスはさらに悪くなります。

不完全な関数: 実際、実際のシナリオに適用すると、tf.function/TorchScript がサポートしていない多くの重要な関数が依然として見つかります。たとえば、カスタム リソースはパッケージ化できず、組み込みのシリアル化のみが可能です。タイプ; 文字列はバイト単位でのみ処理でき、中国語などの Unicode では diff が発生します; コンテナは同形である必要があり、カスタム タイプなどをサポートしていません...

さらに、非対応のタイプも多数あります。 - 深層学習タスク。たとえば、シーケンス アノテーション、言語モデルのデコード、ツリー モデルの人工特徴構築など、自然言語処理には依然として多くの非深層学習アプリケーションやサブタスクが存在します。これらは通常、より柔軟な特徴パラダイムを備えています。エンドツーエンドの統合されたトレーニングとプロモーションのソリューションには、依然として多くの開発と正確性の検証作業が必要です。

上記の問題を解決するために、コンパイルに基づいた前処理ソリューション MATXScript を開発しました。

    3. MATXScript
  • ディープ ラーニング アルゴリズムの開発では、開発者は通常、迅速な反復と実験に Python を使用する一方、C を使用して正確性チェックサムを含む高性能オンライン サービスを開発します。負担が重くなる!
  • MatxScript (https://github.com/bytedance/matxscript) は、Python サブ言語用の AOT コンパイラーであり、Python を C に自動的に変換し、ワンクリックでパッケージ化および公開する機能を提供します。 MATXScript を使用すると、開発者はモデルを迅速に反復しながら、低コストで高パフォーマンスのサービスを展開できます。

コア アーキテクチャは次のとおりです:

  • 最下層は純粋な C/CUDA 基本ライブラリで、高性能オペレーターの専門家によって開発されました。
  • 基本ライブラリに加えて、Python ライブラリが規則に従ってカプセル化されており、トレーニング プロセスで使用できます。
  • 推論が必要な場合は、MATXScript を使用して Python コードを同等の C コードに変換し、それをダイナミック リンク ライブラリにコンパイルし、モデルとその他の依存リソースを追加して、パッケージ化して一緒に公開できます。

その中でもコンパイラの役割は非常に重要であり、その中心的なプロセスは次のとおりです。

バイトダンスモデル大規模展開実戦

上記のプロセスを通じて、ユーザーが作成した前処理コードはパイプラインで JitOp にコンパイルされます。前処理と後処理をモデルとリンクするために、トレース システムも開発しました (インターフェイスの設計は PyTorch を参照しています)。アーキテクチャは次のとおりです。

バイトダンスモデル大規模展開実戦

MATXScript に基づいて、トレーニングと推論に同じコード セットを使用できるため、モデル展開のコストが大幅に削減されます。同時に, アーキ​​テクチャとアルゴリズムは分離されており, アルゴリズムの学生は完全に Python で作業できます. アーキテクチャの学生はコンパイラ開発とランタイムの最適化に焦点を当てます. ByteDance では, このソリューションは大規模な導入によって検証されています!

4. 小さなテスト

MATXScript の使用方法を示す例として、最も単純な英語テキストの前処理を示します。

目標: 英語テキストの一部をインデックスに変換する

  1. 基本的な辞書検索ロジックを作成する
class Text2Ids:
def __init__(self) -> None:
self.table: Dict[str, int] = {
"hello": 0,
"world": 1,
"[UNK]": 2,
}

def lookup(self, word: str)
return self.table.get(word, 2)

def__call__ (self, words: List[str])
return [self.lookup(w) for w in words]
ログイン後にコピー
  1. パイプラインを作成する
import matx

class WorkFlow:
def __init__(self):
# 此处会进行代码编译,Python 代码自动编译封装为 Callable 对象
self.text2ids = matx.script(Text2Ids)()

def process(self, texts):
ids = self.text2ids(texts)
return ids

# test
handler = WorkFlow()
print(handler.process("hello world unknown"))
# output: [0, 1, 2]
ログイン後にコピー
  1. トレース ディスクへのエクスポート
# dump
mod = matx.trace(handler.process, "hello world")
print(mod.run({"texts": "hello world"}))
mod.save('./my_dir')
# load
mod = matx.load('./my_dir', -1)
print(mod.run({"texts": "hello world"}))
ログイン後にコピー
  1. C Load
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <matxscript/pipeline/tx_session.h>
using namespace ::matxscript::runtime;
int main()
{
// test case
std::unordered_map<std::string, RTValue> feed_dict;
feed_dict.emplace("texts", Unicode(U"hello world"));
std::vector<std::pair<std::string, RTValue>> result;
const char* module_path = "./my_dir";
const char* module_name = "model.spec.json";
{
// -1 mean cpu
auto sess = TXSession::Load(module_path, module_name, -1);
auto result = sess->Run(feed_dict);
for (auto& r : result) {
std::cout << "key: " << r.first << ", value: " << r.second << std::endl;
}
}
return 0;
}
ログイン後にコピー

完全なコードについては、https://github を参照してください。 .com/bytedance/matxscript/tree/main/examples/text2ids

要約: 上記は純粋な Python で実装された非常に単純な前処理ロジックであり、一般的な C コードでロードして実行できます。モデル 実際のマルチモーダルなエンドツーエンドのケースを示します。

5. マルチモーダルのケース

ここでは、グラフィック マルチモーダル (Bert Resnet) を例として取り上げます。モデルは、トレーニングとデプロイにおける実際の作業を示すために、PyTorch を使用して作成されています。

  1. 環境の構成
    a. gcc/cuda およびその他のインフラストラクチャの構成 (通常、運用および保守の学生がこれをすでに行っています)
    b. MATXScript とそれに基づいて開発された基本ライブラリをインストールします(テキスト、ビジョンなど)
  2. モデル コードを記述します
    a. ここでは省略していますが、論文やその他のオープン ソース実装を参照して自分で行うことができます
  3. 前処理コードを記述します

a . text

from typing import List, Dict, Tuple
import libcut
import matx
class Vocabulary:
...
def utf8_decoder(s: List[bytes]):
return [x.decode() for x in s]
class TextNDArrayBuilder:
...
class TextPipeline:
def __init__(self, mode: str = "eval"):
self.mode = mode
self.cut_engine = libcut.Cutter('/path/to/cut_models', ...)
self.vocab = matx.script(Vocabulary)('/path/to/vocab.txt')
self.decoder = matx.script(utf8_decoder)
self.input_builder = matx.script(TextNDArrayBuilder)(self.vocab)
def process(self, text: List[bytes]):
# List[bytes] 是对齐 C++ 的 vector<string>
text: List[str] = self.decoder(text)
words: List[List[str]] = self.cut_engine(text)
batch_ids: List[List[int]] = self.vocab(words)
input_ids, segment_ids, mask_ids = self.input_builder(batch_ids, 32)
if self.mode == "train":
return input_ids.torch(), segment_ids.torch(), mask_ids.torch()
return input_ids, segment_ids, mask_ids
ログイン後にコピー

b.vision

from typing import List, Dict, Tuple
import matx
from matx import vision
class VisionPipeline:
def __init__(self,
 device_id: int = 0,
 mode: str = "eval",
 image_size: int = 224,):
self.is_training = mode == 'train'
self.mode = mode
...
def process(self, image,):
if self.is_training:
decode_nds = self.random_crop_decode(image)
flip_nds = self.random_flip(decode_nds)
resize_nds = self.resize(flip_nds)
transpose_nd = self.transpose_norm(resize_nds, vision.SYNC)
else:
decode_nds = self.decode(image)
resize_nds = self.resize(decode_nds)
crop_nds = self.center_crop(resize_nds)
transpose_nd = self.transpose_norm(crop_nds, vision.SYNC)
if self.mode == "trace":
return transpose_nd
return transpose_nd.torch()
ログイン後にコピー
  1. DataLoader に接続
    a. TextPipeline は通常の Python クラスとして使用でき、Dataset に接続できます
    b. VisionPipeline には GPU 前処理が含まれており、バッチ処理に適しています。自分で別の DataLoader を構築する必要があります (ここでポイントを埋め、後で ByteDance の内部マルチスレッド DataLoader をオープンソースします)
  2. 追加モデル コードを入力してトレーニングを開始する Bar
  3. エンドツーエンドの推論モデルをエクスポートする
class MultimodalEvalPipeline:
def __init__(self):
self.text_pipe = TextPipeline(mode="eval", ...)
self.vision_pipe = VisionPipeline(mode="eval", ...)
self.torch_model = torch.jit.load('/path/to/multimodal.jit', map_locatinotallow='cuda:0')
self.tx_model_op = matx.script(self.torch_model, device=0)

def eval(self, texts: List[bytes], images: List[bytes])
input_ids, segment_ids, mask_ids = self.text_pipe.process(texts)
images = self.vision_pipe.process(images)
scores = self.tx_model_op(input_ids, segment_ids, mask_ids, images)
return scores
# examples
example_batch_size = 8
text_examples = ['hello, world'.encode()] * example_batch_size
with open('/path/image.jpg', 'rb') as f:
image_example = f.read()
image_examples = [image_example] * example_batch_size
# pipeline instance
pipe = MultimodalEvalPipeline(...)
mod = matx.trace(pipe.eval, text_examples, image_examples)
# test
print(mod.run({"texts": text_examples, "images": image_examples}))
# save
mod.save('/path/to/my_multimodal')
ログイン後にコピー

概要: 上記の手順を完了すると、エンドツーエンドのトレーニングとトレーニングを完了できます。リリース作業、およびプロセス全体は純粋な Python コードで完了し、アルゴリズムを学生自身が完全に制御できます。もちろん、モデル計算自体にパフォーマンスの問題がある場合は、画像の自動変更と最適化によってバックグラウンドで完了することもできます。

注: 完全なコード例については、https://github.com/bytedance/matxscript/tree/main/examples/e2e_multi_modal

6 を参照してください。前 この章では、アルゴリズムのクラスメイトがリリースしたモデル パッケージを入手し、それを統合サービスを使用してロードして実行する方法について説明します。

完全なサーバーには次のものが含まれます: IDL プロトコル、バッチ処理戦略、スレッド/スレッドのスケジューリングと配置、モデル推論...

ここではモデル推論についてのみ説明します。その他は開発可能です。合意に従って。 main 関数を使用して、モデルのロードと実行のプロセスを示します。

#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <matxscript/pipeline/tx_session.h>
using namespace ::matxscript::runtime;
int main()
{
// test case
std::unordered_map<std::string, RTValue> feed_dict;
feed_dict.emplace("texts", List({String("hello world")}));
feed_dict.emplace("images", List({String("......")}));
std::vector<std::pair<std::string, RTValue>> result;
const char* module_path = "/path/to/my_multimodal";
const char* module_name = "model.spec.json";
{
// cuda:0
auto sess = TXSession::Load(module_path, module_name, 0);
auto result = sess->Run(feed_dict);
for (auto& r : result) {
std::cout << "key: " << r.first << ", value: " << r.second << std::endl;
}
}
return 0;
}
ログイン後にコピー

上記のコードは、C でマルチモーダル モデルをロードする最も単純なケースです。サーバーを開発する学生の場合、次のことを実行するだけで済みます。単純な抽象化と規約を通じて、上記のコードは統一された C モデル サービス フレームワークに変換できます。

7. 詳細情報

私たちは Bytedance-AML-機械学習システム チームであり、統一された高パフォーマンスのトレーニングとプロモーションの統合フレームワークを企業に提供することに尽力しています。 Volcano Engine Machine Learning Platform を通じてパートナー企業にサービスを提供する予定で、Volcano Engine Machine Learning Platform は 2023 年から、プリセットのミラー環境、共通シナリオの公開サンプル、企業のアクセスおよび使用時の技術サポートなどの MATX 関連サポートを提供する予定です。など、トレーニングと推論のシナリオの高速化と統合を低コストで実現できます。弊社製品の詳細については、https://www.volcengine.com/product/ml-platform をご覧ください。

以上がバイトダンスモデル大規模展開実戦の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:51cto.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート