SlideShare une entreprise Scribd logo
1  sur  57
Télécharger pour lire hors ligne
サイバーエージェントにおける
MLOpsに関する取り組み

PyData.Tokyo Meetup #23
MLOps ~ AIを社会に届ける技術
芝田 将
2
Masashi Shibata
● 2017年新卒入社・AI Lab所属

● CyberAgent Developer Experts

● Optunaコミッター

● Kubeflow/Katibレビュアー

● go-prompt, kube-prompt作者

● 共訳書 エキスパートPythonプログラミング 改訂2版

@c-bata @c_bata_
3
今日の内容
機械学習を本番投入していくうえでの取り組み・Pythonまわりの実装テクニック
1. Dynalystの事例紹介
Cythonを使った高速化やメモリ管理
2. AirTrackの事例紹介
ハイパーパラメータ最適化の転移学習
3. AI Messanger Voicebotの事例紹介
軽量スレッドとWebSocketサーバーの話
4
1 Dynalystの事例紹介
Cythonによる高速化やメモリ管理
5
Dynalystにおける機械学習
6
機械学習の重要性
スマートフォン向けのリターゲティング※1広告配
信プラットフォームを開発。
1. 表示する広告はオークションで決まる
2. SSPが、オークションを開始
3. DSPが、購買確率を予測し入札
(どの広告をいくらで表示したいか)
4. 落札者を決定し、その広告を表示
※1 一度反応のあった人(例: 過去にアプリを入れたことがある) に
再度興味を持ってもらえるようにアプローチする広告配信戦略。
機械学習によるユーザー購買確率
(CTR, CVR)の予測精度が売上に直結
7
Field-aware Factorization Machines
https://www.csie.ntu.edu.tw/~cjlin/papers/ffm.pdf
DynalystではCVR予測に利用している手法
● KDD CUPやKaggleのCTR, CVRの予測コ
ンペで好成績を収める※1
● 実装はLIBFFMを使用
(https://github.com/ycjuan/libffm)
● LIBFFMは、C++のライブラリでコマンドライ
ンインターフェイスのみを提供
※1 提案者のYuchin Juanさんらは、CTR予測のKaggleコンペでもFFMを使って2度優勝
8
LIBFFMへの
機能追加
LIBFFMには追加でパッチをあてて利用
● 遅れコンバージョン問題に対処するた
め、因果推論の手法を機械学習の損
失関数に組み込む。
● DynalystにおいてA/Bテストを実施し
た結果、売上が約30%増加。
https://dl.acm.org/doi/10.1145/3366423.3380032
Pythonバインディングも自前で実
装する必要がある
9
高速化の重要性
2019年時点の公開情報でDynalystのトラ
フィックは、数十万リクエスト/秒。
→ 高いスループットが求められる。
大規模広告配信プロダクトの今後と課題 by 黒崎 優太 (Feb. 2019) より参照
広告の表示が遅れないように、RTBでは大
体100ms以内にレスポンスを返さなければ
ならない。
→ レスポンスタイムも重要。
機械学習によるCTRやCVRの予測 (推
論処理) も高速化が不可欠。
10
Cythonによる
推論サーバーの高速化
11
推論サーバー (gRPC) 

学習パイプライン

推論サーバー

12
Cythonとは
PythonとC/C++の静的型システムを融合したプ
ログラミング言語。
● Cythonのソースコードを入力に、効率的な
C拡張モジュールを生成 ※1
● Pythonのスーパーセットな言語。静的型情
報を与えるほど高速なコードを生成
● C/C++とPythonとのインターフェイスとして
も利用可能
In [1]: %load_ext cython
In [2]: def py_fibonacci(n):
...: a, b = 0.0, 1.0
...: for i in range(n):
...: a, b = a + b, a
...: return a
In [2]: %%cython
...: def cy_fibonacci(int n):
...: cdef int i
...: cdef double a = 0.0, b = 1.0
...: for i in range(n):
...: a, b = a + b, a
...: return a
In [4]: %timeit py_fibonacci(10)
582 ns ± 3.72 ns per loop (...)
In [5]: %timeit cy_fibonacci(10)
43.4 ns ± 0.14 ns per loop (...)
※1 手書きのCコードより高速になることも珍しくない。また移植性も高く、多く
のPythonバージョンやCコンパイラをサポートする。
13
Cythonによる
高速化
必要なステップは主に次の5つ
1. Cythonファイルの用意 (拡張子は .pyx)
2. cdefキーワードによる静的な型宣言
3. コードアノテーションの確認 ※1
4. setuptoolsスクリプトを用意
5. C拡張モジュールのコンパイル
from setuptools import setup, Extension
from Cython.Build import cythonize
setup(
...,
ext_modules=cythonize([
Extension("foo", sources=["foo.pyx"]),
]),
)
※1 cythonコマンド(cython -a foo.pyx)や、cythonize(..., annotate=True)オプ
ション、IPythonマジックコマンド(%%cython -a)で生成可能。
# cython: language_level=3
def predict(float[:, :, :] weights, float[:, :] x):
cdef float result
...
return result
# Cレベル関数宣言
cdef float sigmoid(float x):
return 1.0 / (1.0 + e ** (-x))
$ python setup.py build_ext --inplace
14
GILの解放
GIL (Global Interpreter Lock)
● GILを持つ(OSレベル)スレッドだけが
Pythonバイトコードを実行できる ※1
● マルチスレッドを使ってもプロセッサコアの
レベルでは並列に処理されない
● Python/C APIを利用せず、Pythonの
データ構造にも触れない箇所では、GILを
明示的に解放できる ※2
def fibonacci(kwargs):
cdef double a
cdef int n
n = kwargs.get('n')
with nogil:
a = fibonacci_nogil(n)
return a
cdef double fibonacci_nogil(int n) nogil:
...
Python/C APIを呼ぶ行は黄
色く表示される。
純粋なCの関数
※1 各スレッドは5ms実行するとロックを受け渡す
※2 Cのレベルでは、PY_BEGIN_ALLOW_THREADSマクロ /
Py_END_ALLOW_THREADSマクロが呼ばれる。
15
Cython Compiler
Directives
安全性を犠牲にしたさらなる高速化
● cdivision: ZeroDivisionError例外
● boundscheck: IndexError例外
● wraparound: Negative Indexing
その他よく使うもの
● profile
● linetrace
Python/C APIが一切使われ
ない (ZeroDivisionError例
外を投げたりしない)
16
推論処理の
最適化結果
レイテンシーとスループットの向上。
● FFM推論時間 約10% (90%減少)
● 推論サーバー レイテンシー 約60%
● 推論サーバー スループット 1.35倍※1
※1 単純計算すると、仮にサーバー50台用意して捌いていた場合、38台で十分 (12台分のコストも浮く)。
17
LIBFFMバインディングの実装
参照カウントとNumPy C-API
18
C++ライブラリを
ラップする
1. cdef extern from による宣言。
2. PyMem_Malloc※1でC++構造体初期化。
3. C++コードの呼び出し。
4. 確保したメモリ領域を、PyMem_Freeで解
放。
# cython: language_level=3
from cpython.mem cimport PyMem_Malloc, PyMem_Free
cdef extern from "ffm.h" namespace "ffm" nogil:
struct ffm_problem:
ffm_data* data
ffm_model *ffm_train_with_validation(...)
cdef ffm_problem* make_ffm_prob(...):
cdef ffm_problem* prob
prob = <ffm_problem *> PyMem_Malloc(sizeof(ffm_problem))
if prob is NULL:
raise MemoryError("Insufficient memory for prob")
prob.data = ...
return prob
def train(...):
cdef ffm_problem* tr_ptr = make_ffm_prob(...)
try:
tr_ptr = make_ffm_prob(tr[0], tr[1])
model_ptr = ffm_train_with_validation(tr_ptr, ...)
finally:
free_ffm_prob(tr_ptr)
return weights, best_iteration
※1 from libc.stdlib cimport malloc も利用できますが、PyMem_Mallocは
CPythonのヒープからメモリ領域を確保するため、システムコールの発行回数を抑え
ることができる。特に小さな領域はこちらから確保するほうが効率的
19
C++ (LIBFFM)
Cython
Pythonと連動したメモリ管理
重み配列のメモリ領域確保
ptr = malloc(n*m*k*sizeof(float))
FFMの学習
model = ffm.train()
C++関数呼び出し
ffm_train_with_validation()
Python
重み配列のメモリ領域解放
free(ptr)
オブジェクトの破棄
del model
重み配列をNumPyでラップ
(NumPy C-APIを利用)
Pythonオブジェクト生成
model = ffm.train()
20
参照カウント
Pythonのメモリ管理機構との連動。
● CPythonのメモリ管理は参照カウント※1
● Numpy配列(model._weights)が破棄され
ると同時に、C++配列のメモリ領域を解放し
たい。
● 右で参照カウントが2と表示されるのは、
sys.getrefcount()の呼び出し時に参照が
追加で発生するため。
import ffm
import sys
def main():
train_data = ffm.Dataset(...)
valid_data = ffm.Dataset(...)
# ‘model._weights’の実体は、libffmが確保したC++配列
# Pythonのメモリ管理と連動して適切に deallocateしたい
model = ffm.train(train_data, valid_data)
print(sys.getrefcount(model._weights))
# -> 2
del model
# -> ‘model.weights’ is deallocated.
print("Done")
# -> Done
※1 循環参照による問題を解決するためだけに、Mark&Sweepライクな独自のGCも持っています。“ライク”とつけた理由は @atsuoishimoto氏の解説記事を参照
(URL: https://atsuoishimoto.hatenablog.com/entry/20110220/1298179766)。
21
多次元配列のメモリレイアウト
>>> x = np.arange(12).reshape((3, 4), order='C')
>>> x
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> x.flatten()
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> x = np.arange(12).reshape((3, 4), order='F')
>>> x
array([[ 0, 3, 6, 9],
[ 1, 4, 7, 10],
[ 2, 5, 8, 11]])
>>> x.flatten()
array([ 0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11])
● Numpy配列作成関数(np.ones, np.empty等)のデフォルトレイアウトはすべてC連続。
● Fortran連続なNumPy配列は、np.ones(..., order=’F’) のようにorder引数を指定。
C連続 (C contiguous)
バッファがメモリの連続領域にまとまっていて、
最後の次元がメモリ内で連続
。
Fortran連続 (Fortran contiguous)
バッファがメモリの連続領域にまとまっていて、
最初の次元がメモリ内で連続
。
22
NumPy C-API
コピーなしで安全にC++配列をラップする。
● LIBFFM側でmallocされたメモリ領域は
libc.stdlib.free()で解放
● PyArray_SimpleNewFromData:
C連続な配列のポインターとshape、型情
報を渡して、NumPy配列でラップ
● PyArray_SetBaseObject:
NumPy配列の実体(C++配列のポインタ)
を所有するオブジェクトを指定※1
※1 cnp.set_array_base()が内部で呼び出す。この関数はbaseオブジェクトの参照カ
ウントをついでにインクリメントしてくれる。これを忘れるとNumPy配列が生存している
のに実体は解放されてしまうバグにつながるので注意。
cimport numpy as cnp
from libc.stdlib cimport free
cdef class _weights_finalizer:
cdef void *_data
def __dealloc__(self):
if self._data is not NULL:
free(self._data)
cdef object _train(...):
cdef:
cnp.ndarray arr
_weights_finalizer f = _weights_finalizer()
model_ptr = ffm_train_with_validation(...)
shape = (model_ptr.n, model_ptr.m, model_ptr.k)
# FFMの重みベクトル model_ptr.W をNumpy配列でラップ
arr = cnp.PyArray_SimpleNewFromData(
3, shape, cnp.NPY_FLOAT32, model_ptr.W)
f._data = <void*> model_ptr.W
cnp.set_array_base(arr, f)
free(model_ptr)
return arr, best_iteration
23
【余談】型付きメモリビュー
Cythonの中で扱うだけなら、型付きメモリビュー(Typed Memoryview)の利用を推奨。
# model_ptr.W は、C連続なshape=(n, m, k) の多次元配列
cdef ffm_problem* model_ptr
model_ptr = train_with_validation(...)
# 最後の次元のストライドを 1に(最後の次元が連続 )、それ以外をコロン 1つに設定する ※1
cdef ffm_float[:, :, ::1] mv = <ffm_float[:model_ptr.n, :model_ptr.m, :model_ptr.k]> model_ptr.W
print("配列のsize:", mv.size)
print("配列のshape:", mv.shape)
print("weights[0, 0, 0] の値:", mv[0, 0, 0])
※1 Fortran連続(最初の次元が連続)な配列の型付きメモリービューは、 cdef ffm_float[::1, :, :] mv のように宣言する。他のレイアウトにも対応できるが、C連続 or Fortran連
続にしておくとCythonはストライドアクセスを計算に入れないより効率的なコードを生成できる。
● memoryview風のインターフェイスを提供。Cレベルでバッファを直接操作するより簡単。
● Pythonのオーバーヘッドがかからない(Python/C APIを呼び出さない)。GILも解除可能。
24
● 機械学習モデルの精度が売上に直結
○ 因果推論の手法を使った遅れコンバージョン問題への対処
○ データコピーなしで安全に配列のメモリー領域を管理
● 大量のトラフィック、厳しいレイテンシー要件 (100ms以内)
○ Cythonを使った推論処理の高速化
○ スループット1.35倍、レイテンシー60%
Dynalystでの取り組みまとめ
25
2 AirTrackの事例紹介
OptunaとMLflowを使ったハイパー
パラメータ最適化の転移学習
26
AirTrackの学習パイプライン
27
AirTrack
位置情報を活用した来店計測や広告配信を行う
● オフラインの行動にもとづくターゲティングを
実現
● GPSから取得した位置情報を(個人に紐付
かない形で)利用
● ユーザやエリアの属性推定、店舗への来訪
予測に機械学習を利用
機械学習モデルの性能がそのまま
プロダクトの武器になる
28
学習
パイプライン
学習パイプラインは、定期的に実行。新し
いデータでモデルを再学習。
● AWS Step Functionsで構築
● 各種メトリクスの収集やモデルの管
理にはMLflowを利用
最適なハイパーパラメーターもOptuna
で毎回探索する。
29
MLflow
MLライフサイクルを管理するプラットフォー
ム。AirTrackでの用途は2つ。
● パラメーターやメトリクス 、アーティファ
クトを収集する。
● 学習済みモデルをバージョニング・管
理する。
# Experimentに紐付け
mlflow.set_experiment("train_foo_model")
# MLflow Runを新しく生成 & 紐付け
with mlflow.start_run(run_name="...") as run:
# MLflow Model Registryにモデルを登録
model = train(...)
mv = mlflow.register_model(model_uri, model_name)
MlflowClient().transition_model_version_stage(
name=model_name, version=mv.version,
stage="Production"
)
# パラメーターを保存 (Key-Value形式)
mlflow.log_param("auc", auc)
# メトリクスを保存 (Key-Value形式)
mlflow.log_metric("logloss", log_loss)
# アーティファクトを保存
# (RDBではなくS3とかで管理したいファイル等 )
mlflow.log_artifacts(dir_name)
MLflowの用語
1. Run: 1回の実行単位
2. Experiment: Runをグルーピング
30
Optunaの基礎知識と
Warm Starting CMA-ES
31
Optuna
PFN社が開発・公開しているハイパーパ
ラメータ最適化ライブラリ
● Define-by-Runスタイルによる柔
軟な探索空間の定義
● 豊富なアルゴリズムのサポート
● プラガブルなストレージバックエンド
● シンプルな分散最適化機構
● リッチなWeb Dashboard
https://github.com/optuna/optuna
import optuna
def objective(trial):
regressor_name = trial.suggest_categorical(
'classifier', ['SVR', 'RandomForest']
)
if regressor_name == 'SVR':
svr_c = trial.suggest_float('svr_c', 1e-10, 1e10, log=True)
regressor_obj = sklearn.svm.SVR(C=svr_c)
else:
rf_max_depth = trial.suggest_int('rf_max_depth', 2, 32)
regressor_obj = RandomForestRegressor(max_depth=rf_max_depth)
X_train, X_val, y_train, y_val = ...
regressor_obj.fit(X_train, y_train)
y_pred = regressor_obj.predict(X_val)
return sklearn.metrics.mean_squared_error(y_val, y_pred)
study = optuna.create_study()
study.optimize(objective, n_trials=100)
32
相関関係を
考慮する手法
探索空間が変化しない場合、ハイパーパ
ラメータ間の相関関係を考慮するアルゴリ
ズムが利用可能※1。

● 多変量TPE

● CMA Evolution Strategy

● ガウス過程ベースのベイズ最適化

※1 デフォルトのアルゴリズムである単変量TPEは、ハイパーパラメータ間の相関関係を考慮しない。
※2 画像は http://proceedings.mlr.press/v80/falkner18a/falkner18a-supp.pdf より参照
最適解の位置が図左のように右上と左下にあるケースを想定
※2。
相関関係を考慮しない手法では真ん中のように左上や右下も多く探索
def objective(trial):
x = trial.suggest_float('x', -10, 10)
y = trial.suggest_float('y', -10, 10)
v1 = (x-5)**2 + (y-5)**2
v2 = (x+5)**2 + (y+5)**2
return min(v1, v2)
33
CMA-ES
ブラックボックス最適化において最も有望な手法の
1つ※1。
● 多変量正規分布から解を生成し、その解の評
価値を利用して、より良い解を生成するような
分布に更新を行う手法
● PythonライブラリをGitHubで公開
○ https://github.com/CyberAgent/cmaes
○ Optunaからも利用が可能

Optuna公式ブログに投稿した解説記事。
https://medium.com/optuna/introduction-to-cma-es-sampler-ee68194c8f88


※1 N. Hansen, The CMA Evolution Strategy: A Tutorial. arXiv:1604.00772, 2016.

34
Warm Starting
CMA-ES
似たようなHPOタスクの試行結果を事前情報と
して活用することで効率的に探索。

● AI Lab 野村将寛が中心となり提案。

● AAAI 2021にて採択

● Optuna v2.6.0から利用可能

# 事前情報として利用する試行結果を
SQLite3のファイルから取り出す
source_study = optuna.load_study(
storage="sqlite:///source-db.sqlite3",
study_name="..."
)
source_trials = source_study.trials
# ターゲットタスクのハイパーパラメータ最適化を実行
study = optuna.create_study(
sampler=CmaEsSampler(source_trials=source_trials),
storage="sqlite:///db.sqlite3",
study_name="..."
)
study.optimize(objective, n_trials=20)
https://www.cyberagent.co.jp/news/detail/id=25561
https://github.com/optuna/optuna/releases/tag/v2.6.0

利用例: 毎週新しいデータでHPOを実行
する際に、先週のHPO試行結果を事前
情報として活用し効率化。
35
前回の試行結果の活用
最新のデータの取得
学習パイプライン Optunaの実行
試行結果を保存
MLflow Artifact
最新のデータの取得
学習パイプライン Optunaの実行
試行結果を保存
MLflow Artifact
AirTrackの来訪予測モデル(XGBoost)で、 オフラインでの性能検証を行い、Optunaのデフォルト
最適化手法と比べて約2倍の高速化 を実現
1週間後
36
Optuna + MLflowを使った
ハイパーパラメータ最適化転移学習
37
Optunaと
MLflowの連携
Optunaの試行結果(SQLite3)は、MLflowの
アーティファクトとして保存

1. 事前情報として利用する試行結果の
取り出し(後述)

2. デフォルトパラメータの評価

3. メトリクスの収集

4. 試行結果のアップロード

mlflow.set_experiment("train_foo_model")
with mlflow.start_run(run_name="...") as run:
# 事前情報として利用する試行結果を取り出す(後述)
source_trials = ...
sampler = CmaEsSampler(source_trials=source_trials)
# 最初にXGBoostのデフォルトパラメーターを挿入
# (デフォルトよりも悪くならないことを保証する
)
study.enqueue_trial({"alpha": 0.0, ...})
study.optimize(optuna_objective, n_trials=20)
# 最適化にまつわるメトリクスの保存
mlflow.log_params(study.best_params)
mlflow.log_metric("default_trial_auc", study.trials[0].value)
mlflow.log_metric("best_trial_auc", study.best_value)
# 探索空間の変化に対応するためのタグ
mlflow.set_tag("optuna_objective_ver", optuna_objective_ver)
# Optunaの最適化結果(db.sqlite3)をアーティファクトに保存
mlflow.log_artifacts(dir_name)
38
前回の試行結果
の取得
先週のHPO試行結果を取り出す。
1. Model Registryから本番で利用して
いるモデルの情報を取得
2. Model InfoからRun IDを取得
3. RunのArtifactsからSQLite3ファイ
ルを取得
4. Optunaの探索空間が変化していな
いことは、タグで識別
def load_optuna_source_storage():
client = MlflowClient()
try:
model_infos = client.get_latest_versions(
model_name, stages=["Production"])
except mlflow_exceptions.RestException as e:
if e.error_code == "RESOURCE_DOES_NOT_EXIST":
# 初回実行時は、ここに到達する。
return None
raise
if len(model_infos) == 0:
return None
run_id = model_infos[0].run_id
run = client.get_run(run_id)
if run.data.tags.get("optuna_obj_ver") != optuna_obj_ver:
return None
filenames = [a.path for a client.list_artifacts(run_id)]
if optuna_storage_filename not in filenames:
return None
client.download_artifacts(run_id, path=..., dst_path=...)
return RDBStorage(f"sqlite:///path/to/optuna.db")
39
MLflow UIから結果を確認
「デフォルトより良いハイパーパラメータが見つかっているかどうか」、
「デフォルトと比べてどのくらい評価指標(AUC)が改善したか」等を確認。
40
XGBoostデフォルト値からの改善量
単変量TPE (初回実行時) Warm Starting CMA-ES
AUC
(詳細は非公開
)
AUC
(詳細は非公開
)
Trial数 (評価回数) Trial数 (評価回数)
enqueue_trialで挿入したXGboostのデ
フォルトハイパーパラメータ
Warm Starting CMA-ESが有望領域を中心に探索
序盤からデフォルトハイパーパラメータよりも良い解を見つける。
41
AirTrackでの取り組みまとめ
機械学習モデルの精度が売上に直結
● 継続的ハイパーパラメータ最適化の実施
● Warm Starting CMA-ESにより先週の試行結果を事前情報
として活用することで探索の効率を大幅に改善
● MLflowとOptunaを使ってシステム導入
42
3 AI Messanger Voicebotの事例紹介
軽量スレッドとWebSocket
43
AI Messanger
Voicebot
AI電話自動応対サービスを開発

● 東京都多摩市:コロナワクチン接種のAI予
約専用ダイアル

● 福井県との実証実験:

道路規制情報に関する電話応対→ 電話
による問い合わせ総数例年比228%へ増
加見込み

機械学習の精度がユーザー体験に直結

https://www.cyberagent.co.jp/news/detail/id=25849
44
システム構成
twilioを経由してWebSocketで音声データをやりとり。
WebSocket
IP電話
45
機械学習システムの開発の難しさ
“In an ML project, the team usually includes data scientists or ML researchers,
who focus on exploratory data analysis, model development, and
experimentation. These members might not be experienced software
engineers who can build production-class services.”
ー MLOps: Continuous delivery and automation... (cloud.google.com)

開発初期の頃、Flaskで実装したWebSocketサーバーが

特定の条件下で固まって動かなくなると相談を受ける。

結構ややこしく、わかりやすい資料もないためハマる人が多そうな問題。

46
WSGIと軽量スレッド
47
Web Server Gateway Interface (PEP 3333)

● WSGIアプリケーションの実体は、callableなオブ
ジェクト (関数など)

● WebSocketのような双方向リアルタイム通信の実
現には工夫が必要 ※1

● WSGIアプリケーションを呼び出したスレッドは、通
信が終わるまで処理を離せない

● Websocketの接続数分のスレッドが必要

WSGIの制限
※1 AI Messanger Voicebotの開発初期に使われていた
Flask-sockets
(Kenneth Reitz作)では、事前に生成した
WebsocketオブジェクトをWSGI
environmentから渡してFlaskから使えるようにしている。


def application(env, start_response):
start_response('200 OK', [
('Content-type', 'text/plain; charset=utf-8')
])
return [b'Hello World']
48
軽量スレッド (グリーンスレッド)
各WebSocketのコネクションにOSネイティブスレッド(threading.Thread)を1つ割り当て
たくない。
● OSのコンテキストスイッチが重たい
○ スレッドの状態(レジスタの内容)をメモリにダンプして、別のスレッドの状態をメ
モリから読み出し処理を再開する
● スレッドのスタックサイズが大きい
○ (システムによりますが) 2MBなど
ユーザーランドで動作するスレッドのようなもの (軽量スレッド) を利用したい。
→ Flask-socketsはGevent-websocketを内部で利用
49
Gevent-websocketの仕組み
50
Gevent
import threading
import time
thread1 = threading.Thread(target=time.sleep, args=(5,))
thread2 = threading.Thread(target=time.sleep, args=(5,))
thread1.start()
thread2.start()
thread1.join()
thread2.join() 実行するとスレッドが 2つ生成され
並行に処理される。
51
Gevent
from gevent import monkey
monkey.patch_all()
import threading
import time
thread1 = threading.Thread(target=time.sleep, args=(5,))
thread2 = threading.Thread(target=time.sleep, args=(5,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
Geventを使うと、1スレッドしかないにもか
かわらず並行に処理されている。
52
from gevent import monkey
monkey.patch_all()
import threading
import time
thread1 = threading.Thread(target=time.sleep, args=(5,))
# -> gevent.Greenlet(gevent.sleep, 5)
...
Gevent
標準ライブラリのブロックする操作を置き換え
threading.Thread → gevent.Greenlet (軽量スレッド)
time.sleep → gevent.sleep
53
WebSocket
Gevent-websocketの仕組み

● Gunicornワーカープロセス生成後に
Monkey patchを呼び出し

● WSGIアプリケーションは、gevent.

Greenlet(軽量スレッド)で呼び出し

● Monkey patchが対応していないものを使
うとブロック

from gevent.pool import Pool
from gevent import hub, monkey, socket, pywsgi
class GeventWorker(AsyncWorker):
def init_process(self):
# プロセス生成後に Monkeypatchをあてる
monkey.patch_all()
...
def run(self):
servers = []
for s in self.sockets:
# Greenlet(軽量スレッド)プールを用意
pool = Pool(self.worker_connections)
environ = base_environ(self.cfg)
environ.update({"wsgi.multithread": True})
server = self.server_class(
s, application=self.wsgi, ...
)
server.start()
servers.append(server)
gunicorn/workers/ggevent.py#L37-L38
このプロダクトでは、Text-to-Speech APIのSDK
が内部でgRPC 双方向ストリーミングを利用して
いたことが原因でした。
54
【余談】ASGIについて
Asynchronous Server Gateway Interface
https://asgi.readthedocs.io/en/latest/specs/main.html
● Djangoコア開発者のAndrew Godwinを中心に仕様を策定
○ WebSocketもサポートできるようなインターフェイス
○ ASGI互換ライブラリ: Uvicorn, Starlette (FastAPI)など
● とはいえ、まだまだこれから...
○ DB-API(PEP 249)の非同期インターフェイスの不在
○ SQLAlchemyの非同期対応もPostgreSQL(asyncpg)のみ
● WebSocketが必要なときなどは適宜使っていきましょう
まとめ
56
まとめ
機械学習システムの開発はさまざまな難しさがある。
今回の発表では社内サポートを通して取り組んできた内容を紹介。
● Cythonによる高速化
● C++ライブラリのラップとメモリ管理
● OptunaとMLflowを使ったハイパーパラメータ最適化の転移学習
● WSGIとGevent-websocketの仕組み
WE’RE HIRING
57
ご応募お待ちしております
https://cyberagent.ai/careers/

Contenu connexe

Tendances

Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化Yusuke Fujimoto
 
変分ベイズ法の説明
変分ベイズ法の説明変分ベイズ法の説明
変分ベイズ法の説明Haruka Ozaki
 
不老におけるOptunaを利用した分散ハイパーパラメータ最適化 - 今村秀明(名古屋大学 Optuna講習会)
不老におけるOptunaを利用した分散ハイパーパラメータ最適化 - 今村秀明(名古屋大学 Optuna講習会)不老におけるOptunaを利用した分散ハイパーパラメータ最適化 - 今村秀明(名古屋大学 Optuna講習会)
不老におけるOptunaを利用した分散ハイパーパラメータ最適化 - 今村秀明(名古屋大学 Optuna講習会)Preferred Networks
 
機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門hoxo_m
 
機械学習による統計的実験計画(ベイズ最適化を中心に)
機械学習による統計的実験計画(ベイズ最適化を中心に)機械学習による統計的実験計画(ベイズ最適化を中心に)
機械学習による統計的実験計画(ベイズ最適化を中心に)Kota Matsui
 
全力解説!Transformer
全力解説!Transformer全力解説!Transformer
全力解説!TransformerArithmer Inc.
 
You Only Look One-level Featureの解説と見せかけた物体検出のよもやま話
You Only Look One-level Featureの解説と見せかけた物体検出のよもやま話You Only Look One-level Featureの解説と見せかけた物体検出のよもやま話
You Only Look One-level Featureの解説と見せかけた物体検出のよもやま話Yusuke Uchida
 
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...joisino
 
近年のHierarchical Vision Transformer
近年のHierarchical Vision Transformer近年のHierarchical Vision Transformer
近年のHierarchical Vision TransformerYusuke Uchida
 
最適輸送の解き方
最適輸送の解き方最適輸送の解き方
最適輸送の解き方joisino
 
[DL輪読会]Deep Learning 第15章 表現学習
[DL輪読会]Deep Learning 第15章 表現学習[DL輪読会]Deep Learning 第15章 表現学習
[DL輪読会]Deep Learning 第15章 表現学習Deep Learning JP
 
Optimizer入門&最新動向
Optimizer入門&最新動向Optimizer入門&最新動向
Optimizer入門&最新動向Motokawa Tetsuya
 
【DL輪読会】High-Resolution Image Synthesis with Latent Diffusion Models
【DL輪読会】High-Resolution Image Synthesis with Latent Diffusion Models【DL輪読会】High-Resolution Image Synthesis with Latent Diffusion Models
【DL輪読会】High-Resolution Image Synthesis with Latent Diffusion ModelsDeep Learning JP
 
【メタサーベイ】数式ドリブン教師あり学習
【メタサーベイ】数式ドリブン教師あり学習【メタサーベイ】数式ドリブン教師あり学習
【メタサーベイ】数式ドリブン教師あり学習cvpaper. challenge
 
cvpaper.challenge 研究効率化 Tips
cvpaper.challenge 研究効率化 Tipscvpaper.challenge 研究効率化 Tips
cvpaper.challenge 研究効率化 Tipscvpaper. challenge
 
畳み込みニューラルネットワークの研究動向
畳み込みニューラルネットワークの研究動向畳み込みニューラルネットワークの研究動向
畳み込みニューラルネットワークの研究動向Yusuke Uchida
 
グラフデータ分析 入門編
グラフデータ分析 入門編グラフデータ分析 入門編
グラフデータ分析 入門編順也 山口
 
【DL輪読会】The Forward-Forward Algorithm: Some Preliminary
【DL輪読会】The Forward-Forward Algorithm: Some Preliminary【DL輪読会】The Forward-Forward Algorithm: Some Preliminary
【DL輪読会】The Forward-Forward Algorithm: Some PreliminaryDeep Learning JP
 

Tendances (20)

Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化
 
変分ベイズ法の説明
変分ベイズ法の説明変分ベイズ法の説明
変分ベイズ法の説明
 
不老におけるOptunaを利用した分散ハイパーパラメータ最適化 - 今村秀明(名古屋大学 Optuna講習会)
不老におけるOptunaを利用した分散ハイパーパラメータ最適化 - 今村秀明(名古屋大学 Optuna講習会)不老におけるOptunaを利用した分散ハイパーパラメータ最適化 - 今村秀明(名古屋大学 Optuna講習会)
不老におけるOptunaを利用した分散ハイパーパラメータ最適化 - 今村秀明(名古屋大学 Optuna講習会)
 
機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門
 
機械学習による統計的実験計画(ベイズ最適化を中心に)
機械学習による統計的実験計画(ベイズ最適化を中心に)機械学習による統計的実験計画(ベイズ最適化を中心に)
機械学習による統計的実験計画(ベイズ最適化を中心に)
 
ResNetの仕組み
ResNetの仕組みResNetの仕組み
ResNetの仕組み
 
研究効率化Tips Ver.2
研究効率化Tips Ver.2研究効率化Tips Ver.2
研究効率化Tips Ver.2
 
全力解説!Transformer
全力解説!Transformer全力解説!Transformer
全力解説!Transformer
 
You Only Look One-level Featureの解説と見せかけた物体検出のよもやま話
You Only Look One-level Featureの解説と見せかけた物体検出のよもやま話You Only Look One-level Featureの解説と見せかけた物体検出のよもやま話
You Only Look One-level Featureの解説と見せかけた物体検出のよもやま話
 
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
 
近年のHierarchical Vision Transformer
近年のHierarchical Vision Transformer近年のHierarchical Vision Transformer
近年のHierarchical Vision Transformer
 
最適輸送の解き方
最適輸送の解き方最適輸送の解き方
最適輸送の解き方
 
[DL輪読会]Deep Learning 第15章 表現学習
[DL輪読会]Deep Learning 第15章 表現学習[DL輪読会]Deep Learning 第15章 表現学習
[DL輪読会]Deep Learning 第15章 表現学習
 
Optimizer入門&最新動向
Optimizer入門&最新動向Optimizer入門&最新動向
Optimizer入門&最新動向
 
【DL輪読会】High-Resolution Image Synthesis with Latent Diffusion Models
【DL輪読会】High-Resolution Image Synthesis with Latent Diffusion Models【DL輪読会】High-Resolution Image Synthesis with Latent Diffusion Models
【DL輪読会】High-Resolution Image Synthesis with Latent Diffusion Models
 
【メタサーベイ】数式ドリブン教師あり学習
【メタサーベイ】数式ドリブン教師あり学習【メタサーベイ】数式ドリブン教師あり学習
【メタサーベイ】数式ドリブン教師あり学習
 
cvpaper.challenge 研究効率化 Tips
cvpaper.challenge 研究効率化 Tipscvpaper.challenge 研究効率化 Tips
cvpaper.challenge 研究効率化 Tips
 
畳み込みニューラルネットワークの研究動向
畳み込みニューラルネットワークの研究動向畳み込みニューラルネットワークの研究動向
畳み込みニューラルネットワークの研究動向
 
グラフデータ分析 入門編
グラフデータ分析 入門編グラフデータ分析 入門編
グラフデータ分析 入門編
 
【DL輪読会】The Forward-Forward Algorithm: Some Preliminary
【DL輪読会】The Forward-Forward Algorithm: Some Preliminary【DL輪読会】The Forward-Forward Algorithm: Some Preliminary
【DL輪読会】The Forward-Forward Algorithm: Some Preliminary
 

Similaire à サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23

Wrapping a C++ library with Cython
Wrapping a C++ library with CythonWrapping a C++ library with Cython
Wrapping a C++ library with Cythonfuzzysphere
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門Shiqiao Du
 
PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門Yosuke Onoue
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputingNoboru Irieda
 
Introduction to Chainer and CuPy
Introduction to Chainer and CuPyIntroduction to Chainer and CuPy
Introduction to Chainer and CuPyKenta Oono
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelereaseShiqiao Du
 
Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cythonAtsuo Ishimoto
 
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編Yosuke Onoue
 
LLVM overview 20110122
LLVM overview 20110122LLVM overview 20110122
LLVM overview 20110122nothingcosmos
 
OpenJDK HotSpot C1Compiler Overview
OpenJDK HotSpot C1Compiler OverviewOpenJDK HotSpot C1Compiler Overview
OpenJDK HotSpot C1Compiler Overviewnothingcosmos
 
ディープラーニングフレームワーク とChainerの実装
ディープラーニングフレームワーク とChainerの実装ディープラーニングフレームワーク とChainerの実装
ディープラーニングフレームワーク とChainerの実装Ryosuke Okuta
 
PyCoRAMによるPythonを用いたポータブルなFPGAアクセラレータ開発 (チュートリアル@ESS2014)
PyCoRAMによるPythonを用いたポータブルなFPGAアクセラレータ開発 (チュートリアル@ESS2014)PyCoRAMによるPythonを用いたポータブルなFPGAアクセラレータ開発 (チュートリアル@ESS2014)
PyCoRAMによるPythonを用いたポータブルなFPGAアクセラレータ開発 (チュートリアル@ESS2014)Shinya Takamaeda-Y
 
第3回システム系輪講会:IPDPS'17 の機械学習系論文
第3回システム系輪講会:IPDPS'17 の機械学習系論文第3回システム系輪講会:IPDPS'17 の機械学習系論文
第3回システム系輪講会:IPDPS'17 の機械学習系論文Junya Arai
 
PythonistaがOCamlを実用する方法
PythonistaがOCamlを実用する方法PythonistaがOCamlを実用する方法
PythonistaがOCamlを実用する方法Yosuke Onoue
 
Pythonによる並列プログラミング -GPGPUも-
Pythonによる並列プログラミング   -GPGPUも- Pythonによる並列プログラミング   -GPGPUも-
Pythonによる並列プログラミング -GPGPUも- Yusaku Watanabe
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門伸男 伊藤
 
20190625 OpenACC 講習会 第1部
20190625 OpenACC 講習会 第1部20190625 OpenACC 講習会 第1部
20190625 OpenACC 講習会 第1部NVIDIA Japan
 
Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Kenta Oono
 

Similaire à サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23 (20)

Wrapping a C++ library with Cython
Wrapping a C++ library with CythonWrapping a C++ library with Cython
Wrapping a C++ library with Cython
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
 
PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputing
 
Introduction to Chainer and CuPy
Introduction to Chainer and CuPyIntroduction to Chainer and CuPy
Introduction to Chainer and CuPy
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
 
Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cython
 
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
 
LLVM overview 20110122
LLVM overview 20110122LLVM overview 20110122
LLVM overview 20110122
 
OpenJDK HotSpot C1Compiler Overview
OpenJDK HotSpot C1Compiler OverviewOpenJDK HotSpot C1Compiler Overview
OpenJDK HotSpot C1Compiler Overview
 
ディープラーニングフレームワーク とChainerの実装
ディープラーニングフレームワーク とChainerの実装ディープラーニングフレームワーク とChainerの実装
ディープラーニングフレームワーク とChainerの実装
 
PyCoRAMによるPythonを用いたポータブルなFPGAアクセラレータ開発 (チュートリアル@ESS2014)
PyCoRAMによるPythonを用いたポータブルなFPGAアクセラレータ開発 (チュートリアル@ESS2014)PyCoRAMによるPythonを用いたポータブルなFPGAアクセラレータ開発 (チュートリアル@ESS2014)
PyCoRAMによるPythonを用いたポータブルなFPGAアクセラレータ開発 (チュートリアル@ESS2014)
 
第3回システム系輪講会:IPDPS'17 の機械学習系論文
第3回システム系輪講会:IPDPS'17 の機械学習系論文第3回システム系輪講会:IPDPS'17 の機械学習系論文
第3回システム系輪講会:IPDPS'17 の機械学習系論文
 
PythonistaがOCamlを実用する方法
PythonistaがOCamlを実用する方法PythonistaがOCamlを実用する方法
PythonistaがOCamlを実用する方法
 
Pythonによる並列プログラミング -GPGPUも-
Pythonによる並列プログラミング   -GPGPUも- Pythonによる並列プログラミング   -GPGPUも-
Pythonによる並列プログラミング -GPGPUも-
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
 
20190625 OpenACC 講習会 第1部
20190625 OpenACC 講習会 第1部20190625 OpenACC 講習会 第1部
20190625 OpenACC 講習会 第1部
 
Math works gdlc2019
Math works gdlc2019Math works gdlc2019
Math works gdlc2019
 
Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)
 
C# 3.0 以降
C# 3.0 以降C# 3.0 以降
C# 3.0 以降
 

Plus de Masashi Shibata

MLOps Case Studies: Building fast, scalable, and high-accuracy ML systems at ...
MLOps Case Studies: Building fast, scalable, and high-accuracy ML systems at ...MLOps Case Studies: Building fast, scalable, and high-accuracy ML systems at ...
MLOps Case Studies: Building fast, scalable, and high-accuracy ML systems at ...Masashi Shibata
 
実践Djangoの読み方 - みんなのPython勉強会 #72
実践Djangoの読み方 - みんなのPython勉強会 #72実践Djangoの読み方 - みんなのPython勉強会 #72
実践Djangoの読み方 - みんなのPython勉強会 #72Masashi Shibata
 
Implementing sobol's quasirandom sequence generator
Implementing sobol's quasirandom sequence generatorImplementing sobol's quasirandom sequence generator
Implementing sobol's quasirandom sequence generatorMasashi Shibata
 
DARTS: Differentiable Architecture Search at 社内論文読み会
DARTS: Differentiable Architecture Search at 社内論文読み会DARTS: Differentiable Architecture Search at 社内論文読み会
DARTS: Differentiable Architecture Search at 社内論文読み会Masashi Shibata
 
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 AutumnGoptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 AutumnMasashi Shibata
 
PythonとAutoML at PyConJP 2019
PythonとAutoML at PyConJP 2019PythonとAutoML at PyConJP 2019
PythonとAutoML at PyConJP 2019Masashi Shibata
 
Djangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationDjangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationMasashi Shibata
 
Django REST Framework における API 実装プラクティス | PyCon JP 2018
Django REST Framework における API 実装プラクティス | PyCon JP 2018Django REST Framework における API 実装プラクティス | PyCon JP 2018
Django REST Framework における API 実装プラクティス | PyCon JP 2018Masashi Shibata
 
Django の認証処理実装パターン / Django Authentication Patterns
Django の認証処理実装パターン / Django Authentication PatternsDjango の認証処理実装パターン / Django Authentication Patterns
Django の認証処理実装パターン / Django Authentication PatternsMasashi Shibata
 
RTMPのはなし - RTMP1.0の仕様とコンセプト / Concepts and Specification of RTMP
RTMPのはなし - RTMP1.0の仕様とコンセプト / Concepts and Specification of RTMPRTMPのはなし - RTMP1.0の仕様とコンセプト / Concepts and Specification of RTMP
RTMPのはなし - RTMP1.0の仕様とコンセプト / Concepts and Specification of RTMPMasashi Shibata
 
システムコールトレーサーの動作原理と実装 (Writing system call tracer for Linux/x86)
システムコールトレーサーの動作原理と実装 (Writing system call tracer for Linux/x86)システムコールトレーサーの動作原理と実装 (Writing system call tracer for Linux/x86)
システムコールトレーサーの動作原理と実装 (Writing system call tracer for Linux/x86)Masashi Shibata
 
Golangにおける端末制御 リッチなターミナルUIの実現方法
Golangにおける端末制御 リッチなターミナルUIの実現方法Golangにおける端末制御 リッチなターミナルUIの実現方法
Golangにおける端末制御 リッチなターミナルUIの実現方法Masashi Shibata
 
How to develop a rich terminal UI application
How to develop a rich terminal UI applicationHow to develop a rich terminal UI application
How to develop a rich terminal UI applicationMasashi Shibata
 
Webフレームワークを作ってる話 #osakapy
Webフレームワークを作ってる話 #osakapyWebフレームワークを作ってる話 #osakapy
Webフレームワークを作ってる話 #osakapyMasashi Shibata
 
pandasによるデータ加工時の注意点やライブラリの話
pandasによるデータ加工時の注意点やライブラリの話pandasによるデータ加工時の注意点やライブラリの話
pandasによるデータ加工時の注意点やライブラリの話Masashi Shibata
 
Pythonistaのためのデータ分析入門 - C4K Meetup #3
Pythonistaのためのデータ分析入門 - C4K Meetup #3Pythonistaのためのデータ分析入門 - C4K Meetup #3
Pythonistaのためのデータ分析入門 - C4K Meetup #3Masashi Shibata
 
テスト駆動開発入門 - C4K Meetup#2
テスト駆動開発入門 - C4K Meetup#2テスト駆動開発入門 - C4K Meetup#2
テスト駆動開発入門 - C4K Meetup#2Masashi Shibata
 
Introduction of PyCon JP 2015 at PyCon APAC/Taiwan 2015
Introduction of PyCon JP 2015 at PyCon APAC/Taiwan 2015Introduction of PyCon JP 2015 at PyCon APAC/Taiwan 2015
Introduction of PyCon JP 2015 at PyCon APAC/Taiwan 2015Masashi Shibata
 

Plus de Masashi Shibata (20)

MLOps Case Studies: Building fast, scalable, and high-accuracy ML systems at ...
MLOps Case Studies: Building fast, scalable, and high-accuracy ML systems at ...MLOps Case Studies: Building fast, scalable, and high-accuracy ML systems at ...
MLOps Case Studies: Building fast, scalable, and high-accuracy ML systems at ...
 
実践Djangoの読み方 - みんなのPython勉強会 #72
実践Djangoの読み方 - みんなのPython勉強会 #72実践Djangoの読み方 - みんなのPython勉強会 #72
実践Djangoの読み方 - みんなのPython勉強会 #72
 
Implementing sobol's quasirandom sequence generator
Implementing sobol's quasirandom sequence generatorImplementing sobol's quasirandom sequence generator
Implementing sobol's quasirandom sequence generator
 
DARTS: Differentiable Architecture Search at 社内論文読み会
DARTS: Differentiable Architecture Search at 社内論文読み会DARTS: Differentiable Architecture Search at 社内論文読み会
DARTS: Differentiable Architecture Search at 社内論文読み会
 
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 AutumnGoptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
 
PythonとAutoML at PyConJP 2019
PythonとAutoML at PyConJP 2019PythonとAutoML at PyConJP 2019
PythonとAutoML at PyConJP 2019
 
Djangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationDjangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django application
 
Django REST Framework における API 実装プラクティス | PyCon JP 2018
Django REST Framework における API 実装プラクティス | PyCon JP 2018Django REST Framework における API 実装プラクティス | PyCon JP 2018
Django REST Framework における API 実装プラクティス | PyCon JP 2018
 
Django の認証処理実装パターン / Django Authentication Patterns
Django の認証処理実装パターン / Django Authentication PatternsDjango の認証処理実装パターン / Django Authentication Patterns
Django の認証処理実装パターン / Django Authentication Patterns
 
RTMPのはなし - RTMP1.0の仕様とコンセプト / Concepts and Specification of RTMP
RTMPのはなし - RTMP1.0の仕様とコンセプト / Concepts and Specification of RTMPRTMPのはなし - RTMP1.0の仕様とコンセプト / Concepts and Specification of RTMP
RTMPのはなし - RTMP1.0の仕様とコンセプト / Concepts and Specification of RTMP
 
システムコールトレーサーの動作原理と実装 (Writing system call tracer for Linux/x86)
システムコールトレーサーの動作原理と実装 (Writing system call tracer for Linux/x86)システムコールトレーサーの動作原理と実装 (Writing system call tracer for Linux/x86)
システムコールトレーサーの動作原理と実装 (Writing system call tracer for Linux/x86)
 
Golangにおける端末制御 リッチなターミナルUIの実現方法
Golangにおける端末制御 リッチなターミナルUIの実現方法Golangにおける端末制御 リッチなターミナルUIの実現方法
Golangにおける端末制御 リッチなターミナルUIの実現方法
 
How to develop a rich terminal UI application
How to develop a rich terminal UI applicationHow to develop a rich terminal UI application
How to develop a rich terminal UI application
 
Introduction of Feedy
Introduction of FeedyIntroduction of Feedy
Introduction of Feedy
 
Webフレームワークを作ってる話 #osakapy
Webフレームワークを作ってる話 #osakapyWebフレームワークを作ってる話 #osakapy
Webフレームワークを作ってる話 #osakapy
 
Pythonのすすめ
PythonのすすめPythonのすすめ
Pythonのすすめ
 
pandasによるデータ加工時の注意点やライブラリの話
pandasによるデータ加工時の注意点やライブラリの話pandasによるデータ加工時の注意点やライブラリの話
pandasによるデータ加工時の注意点やライブラリの話
 
Pythonistaのためのデータ分析入門 - C4K Meetup #3
Pythonistaのためのデータ分析入門 - C4K Meetup #3Pythonistaのためのデータ分析入門 - C4K Meetup #3
Pythonistaのためのデータ分析入門 - C4K Meetup #3
 
テスト駆動開発入門 - C4K Meetup#2
テスト駆動開発入門 - C4K Meetup#2テスト駆動開発入門 - C4K Meetup#2
テスト駆動開発入門 - C4K Meetup#2
 
Introduction of PyCon JP 2015 at PyCon APAC/Taiwan 2015
Introduction of PyCon JP 2015 at PyCon APAC/Taiwan 2015Introduction of PyCon JP 2015 at PyCon APAC/Taiwan 2015
Introduction of PyCon JP 2015 at PyCon APAC/Taiwan 2015
 

サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23