うめぞーコラム

思ったことを書き綴るだけの内容。IT業界ネタ中心。

AIを支える仕組み

AIを支える仕組みについて

今日はArtificial Intelligence, AI 支える仕組みについて、あまり語られていない視点で語ってみます。

 

IBMが誇るWatsonは、誰もがAIと認識していると思います。クイズに勝ったりチェスに勝ったりと、人知を超えるアクションを起こして「すげぇ!」と言われています。確かに凄いです。だって、人の知識量を遥かに超える情報から、応答すべき答えを、限られた時間内で返すんですから。

でも、ちょっと待って。これってWatsonという、なんだかわからない巨大なブラックボックスでしかできないものなのでしょうか?普通の技術でできないのでしょうか?

クイズの回答を例にとって要素技術を見てみましょう。クイズのプロセスは、1. 質問者からの問いかけがあり、2. 回答者が考えて、3. 回答する。これだけです。素人考えですが、コンピュータ側で行うべき技術要素は下記のようなものでしょう。

 

1. 音声認識により発音された内容を忠実に文字に起こす

2. 起こされた文字情報から、何について回答すべきかを判断する(人名なのか物質名なのか、形容詞なのか... 等)

3. 起こされた文字情報から、予め持っておいたデータから関連性を検索し、スコアリングする

4. スコアリングと情報の関係性を判断し、より的確なものを回答候補とする

5. 複数の回答の候補と2.で判断した回答すべき内容とのマッチングをとり、回答候補を絞り込む

6. スコアリングなどで回答に序列をつけ、最も得点の高いものを回答とする

 

もっとも、上記の操作を予め何度も繰り返して、その結果自体をデータとして持っておくことも必要でしょう。

 

この一連の動作を、もうちょっと技術よりに抽象的に考えてみます。今までのコンピュータの世界で何が難しかったかというと、

A. 大量のデータを保存しておくこと

B. 大量のデータから情報(データ)を超高速に検索すること

C. データとデータの関連性をマッチングしてアクションを起こすこと

D. 超高速で処理をすること

かなと思います。この4つについて解決方法を考えてみます。

 

A. 大量のデータの保存

 データの保存 というと、ファイルとかデータベースとかになりますが、通常の使い方であればそれで良いです。AIの世界になると情報量がとんでもなく必要になります。ギガとかテラとかではなく、ペタ(千兆)とかエクサ(100京)という、私が産まれた後に国際単位系にて制定(!) された単位を持つ量です。単一のファイルシステムとかデータベースでは容量が少なすぎて使い物になりません。そのため、複数のファイルシステム、複数のデータベースを連結して使うことになります。

 

B. 大量のデータから情報(データ)を超高速に検索すること

 「データを単に入れておくだけ」であれば、入れ物さえデカくすれば目的は達成ですが、使われないデータを貯めていても、それはゴミ屋敷と同じです。データがどのような目的で使われるかを意識してデータを貯める必要があります。それはデータの保存形態をどうするかに直結します。1件1件バラバラに、名刺を箱の中に入れておくようなデータとするのか、データを正規化して複数のテーブルに関係性(Relational)を持っておくようなデータとするのか、1件1件のデータはバラバラでもそれぞれが前後関係という関係性で繋がるデータとするのか、など。

 今までの業務処理でよく使われているのはRelational DBです。OracleとかPostgreSQLとか、皆さんもよく耳にするアレです。異なる性質のデータの塊を、関連性を持つキーで繋げているので、そのキーで検索することで、異なるデータ間で一貫性を保つことができるわけです。

 一方、Relational DBが出てくる前にMainframeのような大型コンピュータでよく使われていたのが、Network DBです。例えば、あるデータを抽出し、その関連性を見る必要があるような場合、記録媒体(昔はテープだった!)へのアクセスに負荷をかけること無く芋づる式に取得・格納できるのがメリットでした。イメージしやすいのはWebのページのリンクみたいなものです。あるページを検索して表示したら、そのページに記事に関連するURLが書いてある みたいな感じと考えるとわかりやすいと思います。記憶媒体のアクセスがシーケンシャルからランダムアクセスになり高速になったことで、使われなくなりましたが、考え方自体はWebのページのリンクように残っています。

 

つまり、大量のデータを保存するためには、使われ方を考え、高速性も考えると複数のアクセスエントリーをもち、複数の独立したCPUでそれぞれ処理できるような、いわゆる分散処理型データベースが必要になります。記憶媒体も回転するディスクよりももっと高速性のあるメモリ型デバイスにする、さらには1st / 2nd / 3rd キャッシュ等の「目的のデータをいかに早く取り出せるか」の技術、分散環境でも重複や欠落のないデータを提供できる仕組み、要求する「アプリケーション」からのアクセスしやすさ などを考慮する必要があります。

 

C. データとデータの関連性をマッチングしてアクションを起こすこと

 "マッチング" とか、簡単に書いていますが、ここが一番重要なのです。

まず、「データ」をマッチングするにはマッチする「ロジック」が必要になります。何をデータとして何をロジックとするかを考えなければなりません。ロジックはいきなり抽象化できません。こういうデータが来た場合にどの項目を見て、その値が同じだったら(範囲内だったら...等)何をする というのいくつも検討した上で、抽象化できそうであればパラメータ化して初めて「ロジック」が出来上がります。これは「データと知識の分離」という作業になります。

 

この作業を「人」が行うのが「設計」であり、「機械的」に行うのが「機械学習」です。どちらもアウトプットとしてはロジックであり、データが来て初めて動くものになります。

ここで、ロジックの組み方にも一つ工夫が必要です。単に if〜then〜else でロジックをプログラミングすると、何が起きるでしょう?判断するパラメータが増えるに従い、ifの分岐が増えるということは簡単に想像できると思います。しかも、elseまで考えると、「ある条件(Condition)」を一つ書くことで、「どうする(Action)」を2つ書く必要があります。つまり単純計算になりますが、条件数をNとすると、アクションの数としては 2xNの数が生まれてしまいます。ここでみなさんが考えつくのは、ソースコードの量を減らすために if の中に複数の条件を書く、else の下にif を入れ子にする等だと思います。

条件の数が増えるとか条件の組み合わせが変わるたびに修正が必要になるわけですが、このプログラミング方法だと、どこを変更すればどのActionに影響がある(答えが変わってしまう)かを事前調査してから修正する必要があります。この作業、めっちゃ大変です。ましてや、そのロジックが本当に正しいかどうかの検証を、このシステムを使う側の人間に「ここをこう直してよい?」と聞いたところでわかるわけがないのです。この方法では遅かれ早かれ破綻を迎えます。

 

そこで出てくる考え方が「パターンマッチング」です。パターンマッチングは「もしそのデータがある条件に"マッチ" した場合、アクションを起こす」という書き方をします。え?前述のと何が違うかって?パターンマッチングは、「パターン(条件)に当てはまれば実行する、パターンに当てはまらなかったら何もしない」という動作をします。ということはプログラムとしてはどういうことかというと、"else"を書かない というところが一つのポイントになります。

 

elseが無い世界とは、ロジックは「マッチした条件ならxxをする」だけなので、「それ以外」の場合でアクションが必要な場合は、ロジックを明記する必要があります。単純に考えると、ソースコードが増えるじゃん!と思われますが、冷静に考えてみてください。上記のような「修正」をする場合のことを。条件間の相関関係が「疎」になるので、変更したいパラメータがあるところ「だけ」を修正すれば良いのです。従来のif-then-else ではほぼできていない「ロジックを捨てる」ということも容易になります。

 

試行錯誤を繰り返して知識をつけて行かなければならないAIの世界では、この「ある部分のロジックを追加する・書き換える」「正答率が低いことがわかったのでロジックを外す」ということを、とんでもない頻度で行われることになります。従来のプログラミング方法では全く太刀打ちできません。データと知識を分離して実装できるパターンマッチング技術が絶対必要になります。

クイズの例でもありましたが、音声を文字に起こすのも、パターンマッチング技術です。

 

人工知能はデータ + 知識です。データも知識も生き物であり、常に入れ替えが必要になります。データの入れ替えはロジックからデータが分離したことで簡単になっていますが、今後はパターンマッチング技術をもっと取り入れて、知識の入れ替えもより簡単にする必要があります。

 

D. 超高速で処理をすること

現在のフォンーノイマンアーキテクチャで動作する「コンピュータ」は、根本的には同時に行える処理は一つだけです。メモリからデータを持ってきて、命令を実行して、メモリにデータを格納する。これが一つ一つシーケンシャルに行われています。それをCPUのクロック数を上げるとかの技術で人の目にも止まらぬ超高速化をすることで、あたかもマルチタスクで動いているかのように見せています。なので、PCに向かって大好きな音楽を聞きながらこのブログのような記事を書くことが同時にできているように思えます。ありがたや、ありがたや!

しかし、AIの世界ではもっともっと高速に動作させる必要があります。現在の0か1かで動いているコンピュータでは限界があります。情報量を0か1かだけでなく、4とか8とかまで同時に扱えるようにすれば、もっと速く動作するでしょう。それは量子コンピュータが安価に使えるようになりまで待たなければならないです。

 

では現状ではどうすればよいのでしょうか。答えは「分散環境」です。あたかもオーケストラと合唱団が素晴らしい音楽を奏でるように、異なるそれぞれのコンピュータがそれぞれ仕事をして、指揮者がコントロールする世界です。グリッドコンピューティングなんかもその仲間の一つですが、もっと簡単に考えられる仕組みが出てきています。最近良く目にするのが、Graphics Processing Unit (GPU)です。CPUがシーケンシャルな動作なのに対して、GPUは並列動作になります。GPUはコア数を膨大に持つことが可能なので、並列動作環境を作りやすいですが、各コアを跨いだ処理ができません。なので、機械学習のスコアリングのような単純作業に向いています。

 

では、GPU以外の場合ばどうするのでしょう。処理するモジュールのそれぞれを「マイクロサービス」という単位で構成します。サービスとは、「データを投げて問い合わせをしたら、ある程度の処理をして返してくれる単位」と考えると良いです。例えば、病院で会計をする時、カルテを窓口に出しますよね。そうすると医療事務のきれいなお姉さま方が医療行為や投薬に対して点数を計算してお金を計算し、請求金額と明細を作ってくれます。これがサービスです。サービスは、マイクロサービスが複数集まって一つのサービスを構成します。今の例だと、データのチェック、起票や計算すること自体はお姉さま(ディシジョンサービス)がやりますが、そのデータをデータベースに格納するのはデータサービス、請求書や明細書を印刷するのはユーザインターフェースサービスというマイクロサービスの役割です。

 

この、マイクロサービス化された環境は、今の時代は「コンテナ」という入れ物の中で動作させることができるようになりました。コンテナは貨物列車のコンテナと同じで、外に行き先とかが書かれていますが、輸送する会社は中身は知らなくてよいのです。(冷蔵かそうでないか、危険物かそうでないかくらいの分類は必要ですが...)

 

世間的にはKubernatesという技術がオーケストラの指揮者の役割を行い、どのコンテナがどこで動くべきかをコントロールします。それにより、数千ものコンテナを同時に動かしてコントロールすることが可能になっています。また、コンテナ間の動作連携も可能です。これにより、超分散環境で動かすことができて、結果的にハイパースケールなパフォーマンスで処理をすることが可能になりました。

 

 レッドハット社の製品

これらの技術を支えるためのいくつかの基盤は、オープンソースで社会を変えるレッドハット社から出ています。

大量のデータ保管:Red Hat Storage (Ceph, Gluster)

超高速なデータサービス:Red Hat Data Grid, Red Hat AMQ (Kafka)

ディシジョンサービス:Red Hat Decision Manager

超高速な稼働環境:Quarkus, Red Hat Enterprise Linux, Red Hat OpenShift Container Platform