blog

DeNAのエンジニアが考えていることや、担当しているサービスについて情報発信しています

2020.03.26 技術記事

MOV お客様探索ナビ アーキテクチャー道場

by atsushi.morimoto

#automotive #AI #infrastructure

TL;DR

  • タクシー運転中に扱うアプリとして、低遅延を保証するため、Redis を DB として選定したが、問題も多い
  • 20 万本の道路ごとに十数種類の特徴量を扱うが、必要となるデータには「時間特性」「地理特性」があり、これを生かした構成にした
  • 特徴量の種類の多さや、リアルタイムデータに対するデバッグの困難さと戦ってきた
  • このアーキテクチャには、デプロイの複雑さや、Redis が単一障害点になる問題があり、戦いは続く

MOV お客様探索ナビとは

こんにちは。オートモーティブ事業本部、モビリティー・インテリジェント開発部で、サーバーサイドエンジニアを務める morimoto と申します。

タクシー配車アプリ MOV では、タクシー乗務員向けに、AI でお客様がいる可能性が高い走行経路を推薦する「お客様探索ナビ」というサービスを、昨年 12 月より商用化致しました。 中止になった TechCon 2020 では、「お客様探索ナビ」の中でもサーバ API のアーキテクチャーに的を絞り、対面でアーキテクチャー図を見ながら解説し、さらにこのアーキテクチャーについて一緒に議論する、そんな体験ブースを用意していました。 この記事では、その体験に近づけるように、「お客様探索ナビ」のアーキテクチャーの解説を行います。

まず、この AI を使ったサービスのコア技術を紹介し、そこからアーキテクチャー的に面白い点を列挙したあと、図をもとに現在のアーキテクチャーを解説します。 最後に、現状のこのアーキテクチャーの課題を解説します。

プレスリリース AI でタクシーの収益性向上と人手不足解消へ 次世代タクシー配車アプリ「MOV」

そもそも「お客様探索ナビ」のコア技術とは

「お客様探索ナビ」とは、MOV の運用でタクシー車両から収集した移動体データをもとに、道路単位でタクシー需要を予測し、最も効率の良い走行経路を提供します。 この予測に用いる特徴量には、一定の期間の移動体データを統計処理した「統計特徴量」と、直近のリアルタイムデータから予測モデルを用いて求めた「予測特徴量」に分けられます。 また、移動体データ以外にも、道路の走行コストの算出には、道路地図を用いて車線の数や道幅から算出した道路の特徴量や、弊社で独自に作成した走行コストが高いと判断した(危険な U ターン箇所など)道路規制も含まれています。 これらの十数種類の特徴量を使って、道路単位(弊社では、連続する 2 つの交差点の間の道路ごとに道路 ID を付与しています)に、お客様を見つけることができる「予測道路価値」を独自アルゴリズムで算出します。 すべて道路単位にデータを用意しているため、最終的にこの特徴量と価値を使って、価値の高い道路をたどることで、最も効率のよい走行経路を求めることができます。

この「統計特徴量」「予測特徴量」の作成を データサイエンティストチームが、さらに「道路規制」や「走行コスト」を GIS 技術のスペシャリストが、「予測道路価値」や「走行経路」のアルゴリズムの開発をドメインアルゴリズムスペシャリストが開発しています。 これらのコア技術をラップする形で、サーバサイドエンジニア、Android エンジニアが、WebAPI とタクシー乗務員向けアプリとして運用しています。

アーキテクチャー的に面白いポイント

筆者は、サーバサイドエンジニアとしてこの案件に参画しました。 サーバの領域で面白いポイントは以下のとおりだと思います。

  • すべての特徴量は「道路単位」のデータであり、その道路の数はサービスしている神奈川県横浜市のエリアでも 20 万、今後展開する東京都では 45 万と膨大である。
  • 一つの車両に対して、アルゴリズムを実行するためには、必ずしも全ての道路のデータがある必要はなく、時刻で区切られた範囲のデータや、その車両の近傍のデータのみを用いれば良い「時間特性」「地理特性」を持つ。
  • アルゴリズムの実行には、最新のデータが有効なため、移動体データを遅延なくアルゴリズムで使える状態に収集する必要がある。
  • タクシー乗務中に利用するサービスのため、運転中に使用しても安全といえるレベルの低遅延で応答する必要がある。

このシステムで使うデータは道路単位であり、数は膨大ですが、実際にアルゴリズムの実行に必要ななデータには時間特性、地理特性が存在します。 それを踏まえて、今後のサービス展開でもスケールする仕組みを考える必要があります。 また、このサービスの安全性を担保するためにも、API の応答速度は一定以上である必要があります。

現在のアーキテクチャー図とサーバ API の周辺

それでは、実際にお客様探索ナビのサーバ API、インフラの現在のアーキテクチャーを解説します。

MOV お客様探索ナビのサーバ API インフラアーキテクチャー図

MOV お客様探索ナビのサーバ API インフラアーキテクチャー図

図の中では、大きく「乗務員アプリ」「移動体プロセッシングワークフロー」「ML-Pipeline」「お客様探索ナビ API」に分かれています。 「お客様探索ナビ API」の前に、前 3 つの説明を加えます。

周辺 1「乗務員アプリ」→「移動体データプロセッシングワークフロー」

「乗務員アプリ」は、実際にタクシー乗務員が使用する Android アプリです。 このアプリから位置情報テレメトリを収集し、そのデータは「移動体データプロセッシングワークフロー」の中で2つの流れに分けられます。 一つは、「リアルタイム移動体データ」として BigQuery に格納され、データサイエンティスト、マシンラーニングエンジニアリングチームが構築する「ML-Pipeline」で「予測特徴量」を生成することに使われます。 もう一つは、移動体テレメトリにマップマッチアルゴリズムを適用し、「高精度道路マッピング移動体データ」として格納します。 これにより移動体データが、緯度経度の座標ベースの走行データから、道路単位のデータに置き換えることができます。

「移動体データプロセッシングワークフロー」については、『オートモーティブの大規模データ処理を支える技術』というタイトルで、発表を行っていますので、こちらもぜひご覧ください。

オートモーティブの大規模データ処理を支える技術 前編:クラウドアーキテクチャ DeNA Engineers Blog

周辺 2「ML-Pipeline」

「ML-Pipeline」では、この「高精度道路マッピング移動体データ」を使って、「統計特徴量」を生成します。 これらの「予測特徴量」と「統計特徴量」は、「ML-Pipeline」によって、日本地図の 2 次メッシュ(10km 四方)ごとにファイル分けされた、道路 ID を列にもつ CSV データとして出力されます。

この「ML-Pipeline」でのエンジニアリングについては『MOV の機械学習システムを支える MLOps 実践』というタイトルで、発表を行っていますので、興味がありましたらぜひ御覧ください。(下記動画、1:01:01 から)

「お客様探索ナビ API」のアーキテクチャー

では、ここから API のためのアーキテクチャーである「お客様探索ナビ API」の部分について解説します。 この部分のメインの仕事は、タクシー車両中の「乗務員アプリ」から「最適探客経路推薦 API」にアクセスされると、「ML-Pipeline」などから得たデータと現在の車両位置を「最適探客経路推薦アルゴリズム」に入力し、得られた経路をアプリに返すことです。

Redis の選定理由

まず、API が使用するデータを格納するデータベースとして、インメモリデータベースである Redis を選択しました。 これには、API ではコアであるアルゴリズムに処理コストを割くために、それ以外のインフラは最も高速なものを選ぼうとした結果になります。 Redis の構築には GCP のマネージドサービスである Google Cloud Memorystore を利用しています。 これより早いデータアクセスの実装を考えると、API の実行インスタンス内にデータを持つことも考えられますが、この方法では利用する乗務員が増えてきたときに、アルゴリズムの実行に必要な CPU のスケールと比例して、メモリも必要になってしまいます。 また、今後のこのサービスのエリア拡大を考えると、エリア拡大に比例してメモリサイズが増加することになります。 そのためにも、メモリのスケールと、CPU のスケールが独立関係になっていることは望ましく、インメモリデータベースと API の実行インスタンスを分けるように設計しました。

どのデータを格納するか

次にどのデータを Redis に格納しておくかがポイントになります。 このシステムで使うデータの特徴として「統計特徴量」にも「時間特性」があります。 すべてのデータを Redis に格納しておくことができれば良いですが、Cloud Memorystore では容量に対して比例してコストがかかります。 コスト最適化を図るならば、直近必要なデータだけを Redis に書き込むようにすることですが、その書き込みサービスは絶対にダウンさせることができないものとなり、運用がシビアになります。 そこで日次でRedis にデータを書き込むサービスを構築し、約 3 日分のデータのみを Redis に書きこむようにしました。 これにより「統計特徴量」の生成や、「統計特徴量」のデータの加工で問題が発生したとしても、1 日は余裕を持って対応することができます。 このサービスの構築には、Google Cloud Composer(依存関係のあるバッチ処理を管理する Apache Airflow のマネージドサービス)を利用しています。

どの単位でデータを格納するか

一方、どの単位にデータを格納するかどうかもポイントになります。 このシステムで扱うデータはすべて道路単位のレコードですが、一般的な RDB のようにレコード単位でデータを格納すると、シーケンシャルクエリが苦手な Redis では Redis の速度を得ることができません。 このシステムでは、3 次地域メッシュと呼ばれる 1km 四方のエリアごとにデータを分割して格納するようにしました。 そして API では車両の 5x5 のメッシュ、つまり 5km 四方のデータを取得し、その範囲でアルゴリズムを動作させています。 API が一度に案内する経路の長さを設計しており、その長さの経路の導出に必要十分なサイズとして設計しました。

Redis の採用により、データ取得にかかるコストは 200ms ほどとなり、この部分の時間コストが支配的にならないようになりました。

リアルタイムデータを遅延なく

移動体データは最新であればあるほど現在の状態をよく反映したデータになるため、遅滞なく最新のデータをアルゴリズムで使えるようになることが有効です。 そのため、「ML-Pipeline」で用いるリアルタイムのデータの流れとは別に、アルゴリズムで直接参照できるデータの流れを用意しています。 それが「位置情報テレメトリ」から「リアルタイム位置情報ストア」に伸びるラインです。 ここでは、現在の車両位置を一元管理する独自開発のデータストアになっています。 ここで用いるデータ配信システムの仕組みについては、 昨年の TechCon で紹介しています ので、ぜひこちらもご覧ください。

全体最適化データ

また、ある車両に示した経路を、あとから来る別の車両に表示したとしても、その経路は空車で走行した直後のため、お客さんがいないことのほうが多いと考えられます。 よって、お客様探索ナビでは他の車輌に示した経路など、複数の車両で最適化するために共有する情報も、Redis に格納しています。

アーキテクチャーで苦しんできたところとその取組

特徴量の種類が多いことへの対策

アーキテクチャー図を見ていただくとわかると思うのですが、特徴量の種類が非常に多いです。 今どのバージョンの特徴量や、道路規制のデータ使って演算しているのか、アルゴリズムはどのバージョンを使っているのかが重要になります。 「ML-Pipeline」と疎のアーキテクチャーにすることで、API では「ML-Pipeline」の提供するデータの管理は不要になりましたが、それでも地図のバージョンや、道路規制のデータのバージョン管理は残ります。 それらを管理するために、アルゴリズムのバージョンは Git のリビジョンと対応させることで、それ以外のデータのバージョンは一つの YAML ファイルを Git 管理することで、その YAML ファイルで度のデータを使っているかが追えるようにしています。

リアルタイムデータをデバッグできる環境の構築

データが多い環境では、アルゴリズムのデバッグも大変です。 リアルタイムデータを活用していると、後からアルゴリズムの結果を再現するためには、その時のデータを再度抽出、加工すると必要があります。 API では、経路を求めるアクセスがあったときに、その時アルゴリズムで使用したデータのバックアップをすべて残すようにしています。 これにより、リアルタイムデータ含めた時刻と地理条件の再現が容易になり、アルゴリズムのデバッグに活用できます。 実際にはドライバーさんから、通行が難しい、危険だとされたレポートが上がってきたときに、どのような条件が揃ってその時刻にその経路が生成されたのか解析するのに使っています。 ちなみに、実証実験で乗務員さんから報告された不自然な経路の多くの原因は、アルゴリズムや予測データの問題よりも、道路地図から求める走行コストの問題や、タクシー乗り場などの抽出ミスであることが多いです。

アーキテクチャーの課題

現在抱えているアーキテクチャーの課題は複数あります。

1. デプロイの複雑さ

一つは、これだけコンポーネントとデータの種類顔多いことによって、デプロイが複雑であることです。 データ間や、アプリケーション間に依存関係があり、正しい順序やバージョンでデプロイする必要があります。 このデプロイの複雑さについては取り組みを行っている最中ですが、デプロイを統一的に管理できるコンソールを用意して、何がデプロイされているのか、何をデプロイしなくてはならないかを人が管理しないようにしようとしています。

2. Redis が単一障害点であること

一つは、Redis が単一障害点になっていることです。 高速化のため Redis を用いていますが、Redis に障害がある場合、機能しないアーキテクチャーになっています。 Cloud Memorystore は十分安定して動作しており、商用化してから障害は発生していませんが、単一障害点であることには変わりありません。 この部分については、Redis が障害時に縮退運転できるストレージサービスを検討しています。

3. コスト

一つは、コストについてです。 Redis は非常に高速ですが、データ量に比例した費用がかかります。 利用ユーザ数に応じて費用がかかるのは理解できますが、サービス提供エリアを拡大するたびに、ユーザ数を問わずサービスエリアの範囲がそのままダイレクトにコストにかかってきます。 また精度を良くするために特徴量の種類を増やすと、それがそのままコストになります。 この部分はまだ考える余地があると思います。

おわりに

MOV お客様探索ナビの現状のアーキテクチャーと、課題について解説しました。 このプロダクトのアーキテクチャーで何を目指して取り組み、また現状の課題を共有できたかと思います。

DeNA の MOV 事業は、Japan Taxi 株式会社と事業統合し、株式会社 Mobility Technologies として次の時代の日本の移動を担う会社になろうとしています。 お客様探索ナビのサービスとその発展サービスを、DeNA の データサイエンティスト、マシンラーニングエンジニアリングチームと一緒に、また事業統合したメンバーと一緒に、新会社でも続ける予定です。 このアーキテクチャーやサービスに興味を持っていただけたならば、DeNA や新会社 Mobility Technologies のエンジニアに声をかけていただければと思います。

最後まで読んでいただき、ありがとうございます!
この記事をシェアしていただける方はこちらからお願いします。

recruit

DeNAでは、失敗を恐れず常に挑戦し続けるエンジニアを募集しています。