[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

ログを ちょこっと grep するツール "ちょこぐれっぷ" つくりました

ログを ちょこっと grep するツール "ちょこぐれっぷ" つくりました

こんにちは! 今日はちょこっとしたツールをつくりました。 ログをちょこっとgrepするツールです。もちろん無料。 chocoGrep - ちょこっとgrep!ログフィルタツールちょこっとgrepするならchocoGrep!「error or warning」と書くだけの簡単or/and検索。AIエージェントに渡す前にログを最適化。正規表現不要、インストール不要。chocoGrepQualiteg Inc. Cursor、Devin、Claude Code、ChatGPT——AIコーディングエージェントにエラーログを渡してデバッグを手伝ってもらう。もう日常ですよね。 でも、 * ログを全部貼り付けたら、AIの応答がやたら遅い * 「トークン制限を超えました」と怒られる * 大量のログの中から、AIが的外れな部分に注目してしまう そこで、つくったちょこっとgrepするためのツールです 名付けて ちょこぐれっぷ!chogoGrep! chocoGrepって何? ブラウザで動く、ゆるいgrepツールです。 ログを貼り付けて、検索ワードを入れるだけ。インストール不要

By Qualiteg プロダクト開発部
GPUを使った分散処理で見落としがちなCPUボトルネックとtasksetによる解決法

GPUを使った分散処理で見落としがちなCPUボトルネックとtasksetによる解決法

こんにちは! 複数枚のGPUをつかった並列処理システムを設計しているときCPUについてはあまり考えないでシステムを設計してしまうことがあります。 「機械学習システムの主役はGPUなんだから、CPUなんて、あんまり気にしなくてよいのでは」 いいえ、そうでもないんです。 推論中のあるタイミングに急に動作が遅くなったりするときCPUが原因であることがけっこうあります。 概要(5分で分かる要点) 先日GPUを使った並列処理システムで、予期しないCPUボトルネックが発生し、パフォーマンスが大幅に低下する問題に遭遇しました。 複数のプロセスが異なるGPUを使用しているにも関わらず、処理が極端に遅くなる現象の原因は、処理パイプラインの一部に含まれるCPU集約的な計算処理でした。 問題の症状 * 単一プロセス実行時:正常な速度 * 複数プロセス並列実行時:処理時間が数倍に増加 * GPUリソースに競合なし(nvidia-smiで確認済み) 根本原因 処理パイプラインにGPUに適さないCPU集約的な計算(データ前処理、統計変換など)が含まれており、複数プロセスが同じCP

By Qualiteg プロダクト開発部
Model Context Protocol完全実装ガイド 2025- 仕様変遷から最新Streamable HTTPまでの全て

Model Context Protocol完全実装ガイド 2025- 仕様変遷から最新Streamable HTTPまでの全て

こんにちは! 現在、LLM業界で破竹の勢いでひろまっているMCPについて、本日はとくに実装面について解説していきたいとおもいます。 MCP、MCPとひとくちにいっていますが、実は短期間でけっこう「標準」とよばれる仕様が変化しておりますので、仕様のバリエーションを順を追って解説しつつ、実際に実装をしていきたいとおもいます。 さて、MCPですが、2024年後半、Anthropicが発表したModel Context Protocol(MCP)は、AI分野における重要な転換点となりました。 従来、各AIベンダーが独自に実装していたツール呼び出し機能(tool useと呼びます)を標準化し、AIモデルと外部システムの連携を統一的に扱える仕組みを提供しました 本記事で、MCPの誕生から現在に至るまでの技術的変遷を詳細に追いながら、2025年時点での最適な実装方法を完全なソースコードと共に解説します。特に、仕様の変化に振り回されがちな実装者の視点から、なぜ現在の形に収束したのか、そして今後どのような実装アプローチを取るべきかを明確にしていきます。 第1章 MCPが解決しようとした問題

By Qualiteg プロダクト開発部
【出展報告】ASCII STARTUP TechDay 2025

【出展報告】ASCII STARTUP TechDay 2025

こんにちは! 本日、「ASCII STARTUP TechDay 2025」に出展してまいりましたのでレポートさせていただきます! ASCII STARTUP TechDay 2025 ASCII STARTUP TechDay 2025は、2025年11月17日(月)に東京・浅草橋ヒューリックホール&カンファレンスで開催された、ディープテック・スタートアップのエコシステム構築をテーマにした展示交流・カンファレンスイベントです。 秋の展示会は本当にいいですね 本日はとてもよいお天気で、涼しくて、展示会にはピッタリの気候で朝からルンルンでした。しかも午後からの展示会ということで、気持ちに余裕をもって朝の業務をこなしていたところ、けっこうすぐに昼前になり、あわてて現場へ。 浅草橋は当社からもわりと近いという立地の良さを甘く見ておりましたが💦、なんとか予定時刻前に到着しました。やっぱり、都心開催は本当にありがたいですね。 会場へ急いでいると、おなかが「ぐ~」と鳴り 「そういえば、朝食まだだったわ」 とおもったところに、なんと私の大好きなエッセンさん🍞のトラックがあるで

By Qualiteg ビジネス開発本部 | マーケティング部