AWS Startup ブログ

AIで高速なキュレーションを実現するストックマークのアーキテクチャ【 Startup Architecture Of The Year 2019 ファイナリストによる寄稿シリーズ 】

皆さんこんにちは、スタートアップマーケティングの石渡です。

先日開催した Startup Architecture Of The Year 2019 では、7社のファイナリストによる熱いピッチコンテストが繰り広げられました。

このイベントは時間の関係もあり、各社5分という限られた時間でのピッチをお願いしました。当日は私も舞台袖から皆さんのピッチを聞いていましたが、ご登壇頂いた皆様の内容は、知恵と経験の詰まったもので、当日イベントに参加されなかった方にも是非お伝えしたいと思いました。そこで、ファイナリストの皆様に寄稿をお願いして、ここ AWS Startup Blog で、各社のアーキテクチャを熱く語って頂くことにいたしました。

今回は、オーディエンス賞に輝いた、ストックマーク株式会社の谷本さんにご登場頂きます。オーディエンス賞は、AWS Summit Tokyoの来場者による投票で決定した、言わばユーザー視線で最も学びのあるアーキテクチャと感じられた賞です。先日、受賞のトロフィーをお渡しするために、ストックマーク様のオフィスにお邪魔してきました。寄稿の前に、写真とショートインタビューをご覧下さい。

写真の右手が谷本さん。ストックマーク様の素敵なオフィスにて、記念品をお渡ししました。

改めて、受賞おめでとうございます。このイベントに応募しようと思ったキッカケなどを教えて下さい。

有り難うございます。実は、第1回目となる 2018年のコンテストには、参加者として会場に居たのです。昨年の時点では、まだAIを本格的に組み込んだ登壇者がいないという印象だったので、今回応募したら面白いかなと考えていました。今回の受賞のニュースなどを見て、採用のご連絡を頂いたりと、色々な反響を頂いていますよ。

現在は約30名の体制と伺っていますが、貴社の開発体制について教えて下さい。

トータルで10名程度のエンジニアによる開発体制です。Asales, Anews, Astrategyという3つのプロダクトごとに、UXデザイナー、フロントエンド、バックエンド、という感じの体制にはなっています。ただ、プロダクト内では各自が複数領域を縦断的に開発できる体制をとっています。また、機械学習やインフラなどは、プロダクト横断的に少数のメンバーが見ていたりもします。少人数の体制でやっていますので、全員がフルスタックエンジニアの様なイメージですね。

ストックマークさんでは、創業当初からAWSをご利用頂いていたのですか?

そうです。創業当初からAWSで開発と運用を続けています。AWSは、弊社のようにアジャイルな開発体制をとっている会社にはフィットしていると思います。2016年の創業当初は、1つの EC2 インスタンスだけというシンプルな構成でしたが、現在はサーバーレスの構成に進化してきています。

このコンテストは、AWS Well-Architeced Framework (W-A) が評価・判断の基準になっています。

W-A のことは、応募してみて初めて知りました。AWS の SA さんと W-A の考え方に基づくレビューを行いましたが、非常に参考になりました。創業当初は、自社プロダクト開発や、目の前の事に精一杯になってしまい、先を見越した設計というのは難しく、問題が起こっては対処療法的にそれに立ち向かうということがありました。ただ、W-A をうまく使えば、ベストプラクティスを理解した上でデザインに取り組めると思うので、有効だと思いました。W-Aレビューでの指摘事項なども踏まえて、早速、本番のアーキテクチャの見直しも行いました。

これからこのコンテストにチャレンジしようという方々にメッセージをお願いします。

創業間もないスタートアップの方だったとしても、AWS の様々なサービスを、W-A を活用した設計を組み合わせることで、色々なことができると思います。このコンテストを一つの通過点として設定して、短時間での仮説検証のサイクルを回していく、というのは有効なアプローチだと思います。W-A もこのコンテストにも、積極的にチャレンジしていくことをお勧めしたいですね。

ストックマークさんのマスコットキャラクターのリスと一緒に。

 

以下、谷本さんによる寄稿文です。

ストックマーク株式会社の谷本と申します。ストックマークではAIによる企業向けの情報収集・企業分析・営業支援サービス(Anews, Astrategy, Asales)を運営しています。

特にAstrategyは「敵を知る、先手を打てる。」をプロダクトの価値として、自社にとってのベンチマーク企業や注目する業界の動向を世界中のニュースメディアや業界レポートからAIが自動で素早く収集・分析して配信することで、VUCAな時代における企業分析を人智を超えて圧倒的に効率化、精緻化します。またAnewsはAIにレコメンドされたニュースを社内で共有することで、コミュニケーションを活性化し、組織のナレッジシェアを促進します。

 

サービスをローンチした2017年当初からAWSを利用しており、サービスの成長にあわせて、AWSによるシステムアーキテクチャの刷新を繰り返しています。現在では1000社以上の導入実績を持つAIシステムがAWS上で運用されています。

今回は、このAIシステムのアーキテクチャについて、AWS Startup Architecture Of The Year 2019で発表させていただいた内容と、発表時には割愛した部分を併せてご紹介します。

発表時のスライドはこちらを参照ください。

AI時代のB2B SaaS アーキテクチャ / AWS Startup Architecture Of The Year 2019

 

AIシステムのアーキテクチャ

システム全体は大きく5つの層に別れています(図2)。はじめに、エンドユーザーが指定したメディア媒体や競合企業名、興味のある技術ワードなどをもとに、世界中のメディアサイトからオープンデータ(ウェブニュース, テックブログ, 業界レポートなど)を収集します。収集したデータはURL単位で独自の自然言語処理エンジンを用いて逐次解析していき、後続の用途別にAmazon S3またはAmazon RDS (Aurora)に保存します。

次に保存済みオープンデータに対して、独自AIエンジンにより要約作成や記事分類(速報ニュースかまとめ系記事かなど)、タグ付け(企業名ラベル、サービス名ラベル、企業買収ニュースラベルなど)を行います。またエンドユーザーのサービス利用ログをもとに、各ユーザーの嗜好ベクトルを算出し、最適なレコメンデーションを作成します。

これらの機械学習処理はバッチアプリケーションとしてEC2で実行しており、AIエンジンの種類とスケール性に応じて、EC2を直接管理するものとAWS Batchで管理するものがあります。AIエンジンのアウトプットはデータ種別にAmazon RDS、Elasticsearch Service、またはAmazon DynamoDBに保存します。

エンドユーザーは、これらオープンデータとAIエンジンが提供するコンテンツを、ブラウザまたはiOSアプリケーションから受け取ります。Webアプリケーションは2層に別れており、永続ストレージへアクセスするアプリケーションはAWS  Elastic Beanstalk、オンラインストレージへアクセスするアプリケーションはAmazon ECSで管理されています。

 

図2: システムを構成する5つの層

 

本AIシステムがこのような5層構造を形成しているのは、機能的な価値として「1/100の時間で、1000倍の情報量」をエンドユーザーに提供し、顧客価値の向上に寄与することを目的としているためです。システムに分割すると、各層には以下のような課題が定義されます。

 

  • 記事収集・解析層:世界中のメディアサイトから、いかに素早く網羅的に記事を取得して提供することができるか
  • 機械学習バッチアプリケーション層:各記事データとユーザーデータをもとにした独自AIエンジンによる予測、分類計算のスケール性とスピードを担保できるか
  • Webアプリケーション層:エンドユーザーがそのとき欲しい記事、分析結果をリアルタイムに計算して提供することができるか

ではこれらを達成するための各層の仕組みを具体的に見ていきます。

 

記事収集・解析

オープンデータを収集・解析する基盤はサーバーレスアプリケーションを中心に構成されています(図3)。

 

処理の流れとしては、まずデータベースからメディアやユーザー指定の興味ワードを取得して、個別にAmazon SQSにジョブ登録します(Lambda関数A)。次に、各ジョブ定義に従って外部サイトにクローリングを行います(Lambda関数B)。RSSであれば直接クローリングを行いますが、メディアサイトなどは、Puppeteerを用いたNode.jsベースのクローリング用エンジンで各媒体のオープンデータを取得します。取得したデータはその後新規データのみにフィルタリングされ(Lambda関数C)、スクレイピングエンジン(Lambda関数D)に流れていきます。

スクレイピング関数はPythonで記述されており。各記事のタイトルやサムネイル情報などを取得するだけではなく、自然言語処理で記事の言語を判定しています。これにより、特定言語の記事のみを配信することを可能にしています。

最終的に解析された記事は永続ストレージに保存されます(Lambda関数E)。

図3: 記事収集・解析層の構成

 

サービス立ち上げ当初、記事収集・解析処理はEC2で運用していました。しかし開発リソースは限られているため、サービスが成長するにつれて日々増大するデータ量とデータパターンに対応できなくなりました。

そこで、データ量が増えてもサービスとしてスケールする構成にするためにEC2からサーバーレスアプリケーションをベースとしたアーキテクチャに移行しました。処理実行単体をLambda関数で定義し、データ登録層との間をSQSでバッファリングすることで、記事数が増えてもスケールできる構成にするためです。特に世の中の多くのメディアは、新しい記事を配信する時間が個別に定義されていることが多く、過渡的に増大する処理量に素早くスケールアウトすることができます。

図4は実際に特定時間にLambda関数が実行され、並列で記事を収集・解析しているところです。Lambda関数が並列で713個実行されているのを確認できます。

図4: Lambda関数の並列実行の様子

 

またクローリング処理、スクレイピング処理、データ登録処理などスケール性とエンジンリソース要件が異なる処理を、Lambda関数という 小さな粒度に定義することで、スケール性と開発効率を両立させる狙いもあります。

機械学習バッチアプリケーション

永続ストレージに保存された記事情報は、Amazon EC2上のバッチアプリケーションで処理されます。バッチ処理は独自の機械学習エンジンを用いて実装されており、例えば以下のようなタスクを実行します。

 

  • 記事の要約を生成する
  • 記事の主題である人物名、企業名を同定する
  • エンドユーザーの行動ログからユーザー嗜好ベクトルを生成する

各タスクのマシンリソース要件とスケール要件はそれぞれ異なるので、タスクの実行に適したAWSサービスを選定して実行環境を構築しています。

例えばユーザー嗜好ベクトル生成タスクにはfastTextベースの学習モデルを用いており、ユーザーごとに独立したタスクを1日の特定の時間内に多数実行する必要があります。そのためEC2 CPUインスタンスをAWS Batch管理下で複数起動し、Dockerコンテナ上のタスクを並列実行してAmazon DynamoDBに保存しています(図5)。

図5: 機械学習処理サーバー群

 

一方、あるニュース記事の主題となっている企業名を予測するタスクは、弊社が公開している事前学習済みBERTモデルをベースとした学習モデルを利用して実行しています(図6)。この処理は演算処理時間ネックとなるため、学習モデルと実行環境を梱包したDockerコンテナをEC2のGPUインスタンス上で稼働させています。

タスクが完了した記事は予測結果とともにElasticsearch Serviceに保存され、エンドユーザーが検索時に利用します。

 

Webアプリケーション

Webアプリケーション層はユーザー認証やHTMLレンダリングを行うWebアプリケーションサーバー群と、機械学習APIサーバー群で構成されています(図7)。

Webアプリケーションサーバー群はAWS Elastic Beanstalk環境で管理されており、環境内のEC2インスタンス上でRailsアプリケーションが稼働しています。フロントエンドはVue.jsのシングルページアプリケーションです。

フロントエンドからの認証、APIコールなどは全てWebアプリケーションサーバーで処理されますが、機械学習処理を伴うサーバー処理はそれ以外の処理に比べて1処理あたりのCPUリソースとメモリリソースを多く必要とし、スケール要件が異なります。そのため機械学習処理はAmazon ECSで別環境として構築し、Dockerコンテナで稼働しているDjango APIサーバーへと処理を経由するようにしています。

例えばフリーワード記事検索機能では、エンドユーザーが入力したワードでElasticsearchに記事検索をかけたのち、DynamoDBからユーザー嗜好ベクトルを取得して数千記事とユーザーのマッチ度を算出し、各ユーザーに最適な記事を個別に配信しています。

また「注目企業の事例や動向を時系列検索」する機能も提供しています。この機能では、弊社データベースに存在する数100万記事に対して、バッチアプリケーション層で算出した企業名(1記事あたり1-10企業タグづけされている)ごとに注目企業とのマッチ度を計算するため、数千万通りの計算をオンラインで実行する必要があります。そこでNGTを用いて各ベクトルをあらかじめインデックス化しておくことで、高速に近傍ベクトル探索を行うことを可能にしています。

新しい記事がデータ登録されるとNGTインデックスを再作成する必要があるため、NGTインデックスはバッチアプリケーションが更新してS3に都度保存しています。APIアプリケーションはAmazon S3に保存されたNGTインデックスの変更を検知して再読み込みし(図8)、常に新しい記事が検索に引っかかるようにしています。

図7: Webアプリケーションサーバー群

 

図8: NGTをS3からロードするクラスの実装

 

さいごに

いかがでしたでしょうか?

今回はストックマークが運営するB向けAIサービスのシステムアーキテクチャを紹介させていただきました。

ストックマークでは独自の機械学習エンジンを日々進化させており、運用するサービスもスケールしているため、サービスを構成するシステムアーキテクチャもほぼ毎週アップデートしていく必要があります。そのような環境下で実感するのは、AWSが提供しているサービスの豊富さです。

AWSの各種サービスによって、サービスをデプロイするコスト、デプロイしたサービスをデータ分析するコスト、そしてより良いサービスへ更新していくためのシステム移行コストが極小化されていると感じます。それにより高速に仮説検証を繰り返すアジャイルな開発を進めることができています。

今回紹介したシステムアーキテクチャも、サービスローンチ当初はEC2とRDSだけでなんとか運用していましたが(図9)、上記のコストを抑えられているおかげで、我々のような開発人員の限られたスタートアップでも仮説検証のスピードを落とさずシステム開発を継続できています。今後も顧客価値の向上に集中してサービス改善を継続し、そのためのシステムアーキテクチャを日々模索していきたいと考えています。

図9: サービスローンチ時のアーキテクチャ

 

谷本さんによる寄稿は以上です。

【関連情報】

Startup Architecture Of The Yearでの谷本さんの登壇の様子(ログミー提供)