Slide 1

Slide 1 text

Copyright © Acroquest Technology Co., Ltd. All rights reserved. PyCon JP 2024 DAY1 FastAPIのasync defとdefの使い分け Acroquest Technology株式会社 佐々木 峻 1

Slide 2

Slide 2 text

CONFIDENTIAL Copyright © Acroquest Technology Co., Ltd. All rights reserved. 佐々木 峻 Acroquest Technology株式会社 執筆 Interface誌 • 2023年Interface 4月号 ChatGPTについて • 2023年Interface 11月号 ローカルLLMについて • 2024年Interface 8月号 GPU x ローカルLLMについて 開発 • NLP/検索が専門 • LLMを使ったRAGソリューションの開発 資格 • Azure Developer Associate • Azure Data Engineer Associate • Azure Data Scientist Associate

Slide 3

Slide 3 text

目次 Copyright © Acroquest Technology Co., Ltd. All rights reserved. 3 1. Pythonにおける並行処理・並列処理・非同期処理 2. マルチスレッドとasync/await 3. FastAPIでのasync defとdefの違い 4. 検証 5. まとめ

Slide 4

Slide 4 text

Copyright © Acroquest Technology Co., Ltd. All rights reserved. 4 前提 CPUは意外と暇 I/Oを待っている間、CPUは何もしてない。暇。 外部アクセス等のI/O処理が多いとき、CPUはその性能をフルに発揮できてない I/O待ち CPU処理 例)DBアクセスが発生するWebサーバの処理 ※I/O待ちが多い処理を「I/Oバウンド」、I/O待ちではなくCPU処理が多い場合 を「CPUバウンド」と呼ぶ。 今回取り上げたいのはI/Oバウンドな処理 サーバ 処理 I/O待ち サーバ 処理 I/O待ち DBアクセス DBアクセス

Slide 5

Slide 5 text

Copyright © Acroquest Technology Co., Ltd. All rights reserved. 5 前提2 暇してもらっては困る CPUは明らかに暇なのに、何も効率化しないと、 CPUが忙しくないが利用者は待たされる事態となる Aさんのリクエスト 例)DBアクセスが発生するWebサーバの処理で、1プロセス1コアで何も考えずに処理した場合 このあと説明する並列処理、並行処理、非同期処理などで暇をなくすことが重要! Bさんのリクエスト Cさんのリクエスト サーバ 処理 I/O待ち サーバ 処理 サーバ 処理 I/O待ち サーバ 処理 サーバ 処理 I/O待ち サーバ 処理 待機 さらに待機…

Slide 6

Slide 6 text

Copyright © Acroquest Technology Co., Ltd. All rights reserved. 6 Pythonにおける並列処理・並行処理・非同期処理 VS VS 並列処理 並行処理 非同期処理

Slide 7

Slide 7 text

Copyright © Acroquest Technology Co., Ltd. All rights reserved. 7 Pythonにおける並列処理・並行処理・非同期処理 VS VS マルチプロセス マルチスレッド async/await Pythonでの実装方法 並列処理 並行処理 非同期処理

Slide 8

Slide 8 text

CPUコア1 CPUコア1 CPUコア1 それぞれのイメージ Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8 並列処理 並行処理 非同期処理 処理 I/O待ち I/O待ち イベントループ マルチプロセス マルチスレッド async/await 処理 I/O待ち 処理 I/O待ち 処理 I/O待ち 処理 処理 処理 CPUコア2 処理 I/O待ち CPUコア3 処理 I/O待ち • 処理をプロセスとして起動 • プロセスごとにCPUコアを割り 当てて同時並列に処理 プロセス1 プロセス2 プロセス3 スレッド1 スレッド2 スレッド3 • 処理をスレッドとして起動 全スレッドは1コアで動作 • I/O待ち中に他のスレッドが処理を 進めることで同時処理 • 1コアで処理を実施 • I/O待ちの開始終了はイベント ループが管理。待ちが終了次第、 空きを見つけて続きの処理を それぞれ実施 処理 処理 処理 処理 処理 処理 処理 処理 処理

Slide 9

Slide 9 text

Copyright © Acroquest Technology Co., Ltd. All rights reserved. 9 Pythonにおける並列処理・並行処理・非同期処理 並列処理 並行処理 非同期処理 マルチプロセス マルチスレッド async/await • multiprocessingという 標準ライブラリを利用 Pythonでの 実装 • threadingという 標準ライブラリを利用 • async/await機能を利用 • プロセス自体を分けるので CPUリソースを効率よく 使うことができる メリット • API呼び出しなどのI/O バウンドな処理の場合に 高速化が期待できる。 • 共有リソースの実装などが 比較的容易 • API呼び出しなどのI/O バウンドな処理の場合に 高速化が期待できる。 • プロセス間の値の受け渡し などの実装がやや難しい デメリット • コンテキストスイッチが ありスレッドが増えると 速度が低下する • 非同期処理を利用する時 にはasync/await専用の 実装が必要。

Slide 10

Slide 10 text

それぞれのイメージ Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10 なぜスレッドが分かれているのに 順番を待っているのか? CPUコア1 CPUコア1 CPUコア1 並列処理 並行処理 非同期処理 処理 I/O待ち I/O待ち イベントループ マルチプロセス マルチスレッド async/await 処理 I/O待ち 処理 I/O待ち 処理 I/O待ち 処理 処理 処理 CPUコア2 処理 I/O待ち CPUコア3 処理 I/O待ち プロセス1 プロセス2 プロセス3 スレッド1 スレッド2 スレッド3 処理 処理 処理 処理 処理 処理 処理 処理 処理

Slide 11

Slide 11 text

Pythonにおけるマルチスレッドの罠 Copyright © Acroquest Technology Co., Ltd. All rights reserved. 11 1. Javaだとスレッドを分けるとコアを複数利用できるが、 Pythonだと1つのコアしか利用できない ⇒Global Interpreter Lock 2. Pythonの処理系の一つであるCPythonなどにある制約 • JythonなどGILがない処理系もあるので、その場合は 今回の話の対象外 3. Pythonでは一つのプロセスが同時に実行できるスレッドは 一つだけ。 4. なので、CPUを多く使う処理ではマルチスレッドにしても マルチプロセスとは違い高速化はしない。 5. 左のようにI/O待ちがある処理では、I/O待ちのときにス レッドを切り替えて処理を進められる。 並行処理 マルチスレッド 処理 I/O待ち 処理 I/O待ち 処理 I/O待ち

Slide 12

Slide 12 text

それぞれのイメージ Copyright © Acroquest Technology Co., Ltd. All rights reserved. 12 やっていること同じなのでは? CPUコア1 CPUコア1 CPUコア1 並列処理 並行処理 非同期処理 処理 I/O待ち I/O待ち イベントループ マルチプロセス マルチスレッド async/await 処理 I/O待ち 処理 I/O待ち 処理 I/O待ち 処理 処理 処理 CPUコア2 処理 I/O待ち CPUコア3 処理 I/O待ち プロセス1 プロセス2 プロセス3 スレッド1 スレッド2 スレッド3 処理 処理 処理 処理 処理 処理 処理 処理 処理

Slide 13

Slide 13 text

マルチスレッドとasync/await Copyright © Acroquest Technology Co., Ltd. All rights reserved. 13 スレッドの切り替えにもコストがかかる 切り替え時間 並行処理 非同期処理 マルチスレッド async/await 一つのスレッドの中でI/O待ちのときに次 の処理を進めているだけ。 スレッドの切り替えは、async/awaitの処理切替 よりも時間がかかる。(コンテキストスイッチ)

Slide 14

Slide 14 text

マルチスレッドとasync/await Copyright © Acroquest Technology Co., Ltd. All rights reserved. 14 スレッドの切り替えにもコストがかかる スレッド数が増えるとasync/awaitに対してマルチスレッドの方が スレッドの切り替え分処理時間が長くなる 切り替え時間 並行処理 非同期処理 マルチスレッド async/await

Slide 15

Slide 15 text

マルチスレッドとasync/await Copyright © Acroquest Technology Co., Ltd. All rights reserved. 15 async/awaitは実装に慣れが必要(個人の感想です) 1. これまで同期処理しか書いてこなかったエンジニアからすると最初はなじみづらい。 2. async/awaitを使用する場合、その処理内で呼ばれるメソッドなどはすべてasync/awaitを 意識したコードにする必要があり、ライブラリも対応したものしか使えない。 例)requestsライブラリはasyncに対応していない。

Slide 16

Slide 16 text

マルチスレッドとasync/await Copyright © Acroquest Technology Co., Ltd. All rights reserved. 16 async/awaitは実装に慣れが必要(個人の感想です) マルチスレッドの場合

Slide 17

Slide 17 text

マルチスレッドとasync/await Copyright © Acroquest Technology Co., Ltd. All rights reserved. 17 async/awaitは実装に慣れが必要(個人の感想です) async/awaitの場合

Slide 18

Slide 18 text

FastAPIにおけるasync defとdefの違い Copyright © Acroquest Technology Co., Ltd. All rights reserved. 18 async defは非同期処理、defはマルチスレッド 1. FastAPIはPath Operation関数をdefで書いた場合、リクエストを受けたらスレッドを自動 で起こしてくれる。 2. async defで書かれている場合は、非同期処理にとして扱われるため、スレッドは作成され ない。 defを利用する場合 async defを利用する場合

Slide 19

Slide 19 text

FastAPIにおけるasync defとdefの違い Copyright © Acroquest Technology Co., Ltd. All rights reserved. 19 async defは非同期処理、defはマルチスレッド 1. FastAPIはPath Operation関数をdefで書いた場合、リクエストを受けたらスレッドを自動 で起こしてくれる。 2. async defで書かれている場合は、非同期処理にとして扱われるため、スレッドは作成され ない。 async defの中で同期処理を実装すると、シングルスレッドの同期処理になってしまう

Slide 20

Slide 20 text

検証 Copyright © Acroquest Technology Co., Ltd. All rights reserved. 20 async def+同期処理はどれくらい遅くなるのか 1. OpenAIのAPIにリクエストを投げる処理を例に実験してみる。 2. async def+同期処理とdef+同期処理で実装したAPIに、それぞれに1分間に100リクエスト 送ってレスポンスタイムの推移を比較する 環境 1. クラウド上のLinux VM(vCPU:1, メモリ:1GB, OS: Linux) 2. Python 3.12

Slide 21

Slide 21 text

検証 Copyright © Acroquest Technology Co., Ltd. All rights reserved. 21 async def+同期処理とdef+同期処理のAPIエンドポイントを用意する

Slide 22

Slide 22 text

検証 Copyright © Acroquest Technology Co., Ltd. All rights reserved. 22 応答時間の推移 async def + 同期処理の場合 def + 同期処理の場合

Slide 23

Slide 23 text

検証 Copyright © Acroquest Technology Co., Ltd. All rights reserved. 23 応答時間の推移 async def + 同期処理の場合 def + 同期処理の場合 async def + 同期処理の場合はリクエストを 送るにつれてレスポンスタイムが伸びている ⇒リクエストが前の処理待ちで溜まっている

Slide 24

Slide 24 text

まとめ Copyright © Acroquest Technology Co., Ltd. All rights reserved. 24 Pythonにおけるマルチプロセス・マルチスレッド・async/awaitは 処理がCPUバウンドかI/Oバウンドで使い分けるのが良い FastAPIにおけるPath Operation関数のasync defはasync/await、 defはマルチスレッドとして処理される Fast APIのasync def内で同期処理として実装すると、パフォーマンス 問題につながるので、同期処理の場合はdefを使う async defはコンテキストスイッチがない分、マルチスレッドよりも高速 なので、実装さえできれば大量のリクエストをさばきたい場合は有効 1 2 3 4

Slide 25

Slide 25 text

25 ご清聴ありがとうございました。 Copyright © Acroquest Technology Co., Ltd. All rights reserved.