[ChatStream] Web サーバー(ASGI server) の起動

[ChatStream] Web サーバー(ASGI server) の起動

こんにちは! (株)Qualiteg プロダクト開発部 です!

本稿では、 ChatStream 搭載した Webサーバーの起動方法について説明いたします!

uvicorn(内部起動)

ChatStreamは FastAPI/Starlette に対応しているため、 ASGI サーバーで動作させることができます。

uvicorn をコード内で定義するには以下のように実装します

def start_server():
    uvicorn.run(app, host='localhost', port=9999)


def main():
    start_server()


if __name__ == "__main__":
    main()

ソースコード全体

import torch
import uvicorn
from fastapi import FastAPI, Request
from fastersession import FasterSessionMiddleware, MemoryStore
from transformers import AutoTokenizer, AutoModelForCausalLM

from chatstream import ChatStream, ChatPromptTogetherRedPajamaINCITEChat as ChatPrompt

model_path = "togethercomputer/RedPajama-INCITE-Chat-3B-v1"
device = "cuda"  # "cuda" / "cpu"

tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.float16)
model.to(device)

chat_stream = ChatStream(
    num_of_concurrent_executions=2,
    max_queue_size=5,
    model=model,
    tokenizer=tokenizer,
    device=device,
    chat_prompt_clazz=ChatPrompt,
)

app = FastAPI()

app.add_middleware(FasterSessionMiddleware,
                   secret_key="your-session-secret-key",  # Key for cookie signature
                   store=MemoryStore(),  # Store for session saving
                   http_only=True,  # True: Cookie cannot be accessed from client-side scripts such as JavaScript
                   secure=True,  # False: For local development env. True: For production. Requires Https
                   )


@app.post("/chat_stream")
async def stream_api(request: Request):
    # handling FastAPI/Starlette's Request
    response = await chat_stream.handle_chat_stream_request(request)
    return response


@app.on_event("startup")
async def startup():
    # start request queueing system
    await chat_stream.start_queue_worker()


def start_server():
    uvicorn.run(app, host='localhost', port=9999)


def main():
    start_server()


if __name__ == "__main__":
    main()

uvicorn(外部起動)

次に uvicorn 外部起動 のパターンについてみていきましょう。

./example にある example_server_redpajama_simple.py をサーバーとして起動する場合

uvicorn example.web_server_redpajama_simple.py:app --host 0.0.0.0 --port 3000

のようになります。こちらのほうがサーバーとアプリの分離ができていて、より本番に近いアプローチとなります。

uvicornの起動オプション

https://www.uvicorn.org/settings/

ソースコード

example_server_redpajama_simple.py

import torch
import uvicorn
from fastapi import FastAPI, Request
from fastersession import FasterSessionMiddleware, MemoryStore
from transformers import AutoTokenizer, AutoModelForCausalLM

from chatstream import ChatStream, ChatPromptTogetherRedPajamaINCITEChat as ChatPrompt

model_path = "togethercomputer/RedPajama-INCITE-Chat-3B-v1"
device = "cuda"  # "cuda" / "cpu"

tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.float16)
model.to(device)

chat_stream = ChatStream(
    num_of_concurrent_executions=2,
    max_queue_size=5,
    model=model,
    tokenizer=tokenizer,
    device=device,
    chat_prompt_clazz=ChatPrompt,
)

app = FastAPI()

app.add_middleware(FasterSessionMiddleware,
                   secret_key="your-session-secret-key",  # Key for cookie signature
                   store=MemoryStore(),  # Store for session saving
                   http_only=True,  # True: Cookie cannot be accessed from client-side scripts such as JavaScript
                   secure=True,  # False: For local development env. True: For production. Requires Https
                   )


@app.post("/chat_stream")
async def stream_api(request: Request):
    # handling FastAPI/Starlette's Request
    response = await chat_stream.handle_chat_stream_request(request)
    return response


@app.on_event("startup")
async def startup():
    # start request queueing system
    await chat_stream.start_queue_worker()

gunicorn

次は gunicorn を使用する方法についてです。こちらは、本番のAPIサーバーとして、もっとも一般的なアプローチとなります。ここで起動した gunicorn を APIサーバーとして Nginx などの Webサーバーをリバースプロキシとして組み合わせることで、本番システムとして稼働させることができます。

./example にある example_server_redpajama_simple.py をサーバーとして起動する場合

gunicorn example.web_server_redpajama_simple.py:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:3000

(注意:Windows 環境では動作しません)

ソースコード

example_server_redpajama_simple.py

import torch

from fastapi import FastAPI, Request
from fastersession import FasterSessionMiddleware, MemoryStore
from transformers import AutoTokenizer, AutoModelForCausalLM

from chatstream import ChatStream, ChatPromptTogetherRedPajamaINCITEChat as ChatPrompt

model_path = "togethercomputer/RedPajama-INCITE-Chat-3B-v1"
device = "cuda"  # "cuda" / "cpu"

tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.float16)
model.to(device)

chat_stream = ChatStream(
    num_of_concurrent_executions=2,
    max_queue_size=5,
    model=model,
    tokenizer=tokenizer,
    device=device,
    chat_prompt_clazz=ChatPrompt,
)

app = FastAPI()

app.add_middleware(FasterSessionMiddleware,
                   secret_key="your-session-secret-key",  # Key for cookie signature
                   store=MemoryStore(),  # Store for session saving
                   http_only=True,  # True: Cookie cannot be accessed from client-side scripts such as JavaScript
                   secure=True,  # False: For local development env. True: For production. Requires Https
                   )


@app.post("/chat_stream")
async def stream_api(request: Request):
    # handling FastAPI/Starlette's Request
    response = await chat_stream.handle_chat_stream_request(request)
    return response


@app.on_event("startup")
async def startup():
    # start request queueing system
    await chat_stream.start_queue_worker()

いかがでしたでしょうか。ChatStreamが FastAPI/Starlette ベースで実装されているので本番に向けては標準的なアプローチでサーバー構築することが可能です。

ただし、商用環境を考慮しますと、通常、1つの ChatStream APIサーバーだけで運用することは稀で、1つの ChatStream API サーバーを ChatStreamノードと呼び、複数のChatStreamノードでリージョンごとのクラスターを作ります。Qualiteg では、このようなスケールアウト型の負荷対策をさせるシステム構成を推奨しております。

Read more

【ChatStream】大容量のLLMの推論に必要なGPUサーバー構成

【ChatStream】大容量のLLMの推論に必要なGPUサーバー構成

大容量のLLM(大規模言語モデル)の推論に必要なGPUサーバー構成とChatStreamとの連携について詳しく動画で解説しています。 特に、Llama3-70Bモデルを例に、そのメモリ要件(140GBのGPUメモリ)と、この要件を満たすために必要なGPUサーバーおよびGPUクラスターの構成について、取り扱いやすい NVIDIA RTX A6000 GPUを使用した例について説明します。 また、モデル並列化技術(テンソル並列化、パイプライン並列化、データ並列化)とその推論エンジンの選択についても触れ、実際に複数のGPUサーバーを使ったクラスター構成がどのように推論処理を効率的に行うかを示します。 最後に、ChatStreamのLLMノードとは何か、そしてそれをどのようにスケーリングして大量の同時リクエストに対応するかについても解説します。こ の動画は、高性能を必要とするLLMのデプロイメントと運用に興味がある方に特に有益です。

By Join us, Michele on Qualiteg's adventure to innovation
ChatStream🄬でLlama-3-Elyza-JP-8B を動かす

ChatStream🄬でLlama-3-Elyza-JP-8B を動かす

こんにちは、本日は Llama-3-Elyza-JP-8B を使ってみました。 昨日 2024年6月26日に発表(https://prtimes.jp/main/html/rd/p/000000046.000047565.html)された Llama-3-Elyza-JP-8B は 70B 版では「GPT-4」を上回る性能の日本語LLMといわれています。 今回、当社でも Playground 環境に Llama-3-Elyza-JP-8B を搭載して試してみましたのでご紹介します。 70B(700億パラメータ)版は GPT-4 を上回るとのことですので、8B(80億パラメータ)版はGPT-3.5 と比較してみることにいたしました。 (性能比較は https://note.com/elyza/n/n360b6084fdbd の記事に詳しく書いてあります。) AWQ量子化版を使用してみる 今回は、A4000

By Qualiteg プロダクト開発部
AttributeError: module 'torch._dynamo' has no attribute 'mark_static_address' が発生したときの対処法

AttributeError: module 'torch._dynamo' has no attribute 'mark_static_address' が発生したときの対処法

以下のようなエラーが出た場合の対処法 File "/venv/Lib/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context return func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^ File "/venv/Lib/site-packages/transformers/generation/utils.py", line 1744, in generate model_kwargs["past_key_values"] = self._get_cache( ^^^^^^^^^^^^^^^^ File "/venv/Lib/site-packages/transformers/

By Qualiteg プロダクト開発部
[AI新規事業創出]Qualitegセレクション:アイディア創造編①Qualiteg式オンラインブレストの活用術

[AI新規事業創出]Qualitegセレクション:アイディア創造編①Qualiteg式オンラインブレストの活用術

Qualiteg blogを訪問してくださった皆様、こんにちは。Micheleです。AIを活用した新規事業やマーケティングを手がけている私には、クライアントからよく寄せられる質問があります。AIを用いた事業展開を検討されている方々が共通して直面するであろう課題に対して、このブログを通じて私なりの解答をご提供したいと思います。 今日は私のお気に入りのブレスト方法である「Qualiteg式オンラインブレスト」の活用術についてお話ししたいと思います。 場所を変えて気分を変えても良いアイディアは生まれない!? よく、「金曜日は1日ブレストしよう!」という上司の掛け声とともに、いつもと違う雰囲気なら良いアイディアも出るかもしれないといってホテルの会議室などを予約されて1日缶詰でブレストしたが、期待する結果が出なかったとおっしゃるクライアントが非常に多いです。 ブレインストーミングは複数の参加者が自由にアイデアを出し合うことで、新しい発想や解決策を見つける手法です。 批判や評価を一時的に排除し、量を重視して多くのアイデアを集めることが目的です。1950年代に広告業界で生まれたこの手法は

By Join us, Michele on Qualiteg's adventure to innovation