世の中多くのソフトウェアエンジニア開発企業と、世界中から集まるトラフィックをさばくGoogleや OpenAIのようなサービスを作っている企業は何が違うのだろうか。一般的には「規模が違う」「大量の計算機リソースを有する」「無尽蔵に資金がある」などと思われがちだが、一休CTOの伊藤直也氏は「何も変わらない。ただ、彼らは本質的な理論を理解している」と語る。

 本質的な理解とは何か? はてな時代に大規模データを扱うことに悩んで到達した書籍を紹介いただいた。

ニフティで「ココログ」を作り、はてなでCTOとして「はてなブックマーク」などを生み出す過程で、大規模データの構築、検索などの技術を体系化し、それを技術ブログで公開するなどして大規模ウェブサービスの基礎を共有化し、コミュニティを盛り上げた。現在はホテル予約サイト「一休.com」のCTO。
伊藤直也(株式会社一休 執行役員 CTO)
ニフティで「ココログ」を作り、はてなでCTOとして「はてなブックマーク」などを生み出す過程で、大規模データの構築、検索などの技術を体系化し、それを技術ブログで公開するなどして大規模ウェブサービスの基礎を共有化し、コミュニティを盛り上げた。現在はホテル予約サイト「一休.com」のCTO。

「自分たちとGoogleは何が違うのか?」と悩んだ

 新卒で最初に入ったのはニフティでした。当時のニフティは社員500人ぐらいで、協力会社さんを入れると1,000人弱だったと思います。当時は、今と違ってIT系企業というのは別に花形産業ではなかったですから。まだアメリカでGoogleができたばかりの頃でした。ちょうど、ニフティにいたときに出張でGoogleのパロアルトの本社に行ったんですが、まだ500人ぐらいの会社でした。もちろん勢いはありましたけれど。

 その後ニフティからはてなに転職したんですが、当時のはてなはまだ全員で1部屋に入れるぐらいの小さなベンチャーでした。僕が確か6人目か7人目の社員だったと思います。それなりに大会社だったニフティから小さな会社への転職は、親戚には反対されましたけどね(笑)。

 当時は、今と違って、ソフトウェアを作って世の中に公開すると、それだけでもたくさんの人が使ってくれたんです。「SNSでバズらせる」などの施策をしなくても、作って出すだけで、すごく反響がある。世の中にまだまだソフトウェアが足りなかったからだと思います。だから、ソフトウェアを作ることができる力をもっと直接的に使いたいと思ったんです。2004~2005年ごろかな。オープンソースが普及して、各社がAPIを公開して、多くのものを共有化していく「Web 2.0」が話題になっていたころです。

 そのころに、僕らは「はてなブックマーク」などの新しいサービスを作りました。僕たちは、ただのウェブアプリケーションならだいたいのものが作れたんです。その一方で、外を見るとGoogle検索のような巨大なサービスがあった。こういうものは、どう作ればいいのか想像がつかない。

 Googleが作っているものと、自分たちが作っているソフトウェアに技術的な差があり過ぎたんですね。僕らはSNSなんかは作れても、「ウェブ全体を検索する検索エンジンを作れ」と言われても、どうやればいいか分からなかった。

 Googleの人たちは、あんな世界中から大量にアクセスされる検索エンジンを一切止めることなく動かしている。一方の自分たちのサービスの方が構造的にもずっと単純なのに、ちょっとアクセスが増えると障害を起こしてしまう。それを見て、僕は「根本的にプログラミングというか、コンピューターの基礎が分かっていないんだな」と思ったわけです。その当時はGoogleといっても今のように桁外れに資金があったわけでもなかったですから、これは技術力の差だと感じました。Googleも自分たちと同じようなサーバーを、同じように使っていたわけですから。

 ただ、彼らはそのサーバー、つまり計算機を「どう使えばいいか」「どんなプログラムを書けばいいか」をよく知っていたんですね。Googleは当時からコンピューターサイエンスの大学院に行ったような人たちしか採っていませんでしたから。でも、一方の僕たちは、あまり計算機を効率よく使うことができていなかった。それで、僕はLinuxカーネルのソースコードをかなり時間をかけて読んで、じっくりと勉強したんですよ。結果的に、それがすごく重要でした。

 僕はコンピューターサイエンスを勉強してこなかったから、原理原則が分かってなかったんです。ウェブサービスは作れても、根本的な計算の意味が分かっていない。だからすごく大規模な、本当に自分たちの手に負えないようなインターネットスケールの量のデータを目の前にしたときに、「それに対してどういうプログラムを作れば、現実的な時間で検索できるか」というようなことはまるで分かっていなかったんですよね。

 これは僕にとっては本当に切実な問題だったんです。サービスが人気になってアクセスが集中すると、サーバーが落ちるじゃないですか。そうすると当然誰かが夜中に叩き起こされて、走ってデータセンターまで行って、動かなくなったサーバーを復旧したりという作業をするんです。これがくり返されるとみんな疲れて寝不足になるし、中には心身の不調を来す人も出てくる。自分の作ったサービスがヒットしたことで、同僚の具合が悪くなったりしていくわけです。責任を感じました。

 とはいえ解決の糸口も見えず、対症療法をくり返して途方に暮れていたのですが、あるときLinuxカーネル、つまりOSの動作原理という根本的なところを勉強し始めたら、少しずつ問題が改善するようになったんです。でも、それをちゃんと理解するためには道がめちゃくちゃ長いんですよ。目の前の解決しないといけない問題と、長く積み上げていく勉強、両方やるしかなかったんです。

検索エンジンはコンピューターサイエンスの「総合格闘技」

『Introduction to Information Retrieval』(Christopher D.Manning、Prabhakar Raghavan、Hinrich Schütze著、Cambridge University Press)
『Introduction to Information Retrieval』(Christopher D.Manning、Prabhakar Raghavan、Hinrich Schütze著、Cambridge University Press)

 この本は「検索エンジンはこういう考え方で作られていて、こういうアルゴリズムとデータ構造が基礎になっていて、このモデルはこういう特性がある」というようなことが解説されている本です。線形代数や確率・統計を中心に数学的な解説も豊富で、終盤では機械学習とかの話にも触れます。これ一冊で、情報検索、リコメンドエンジン、機械学習、そしてその先で生成AIにつながる要素まで理解できる知識が得られました。

 もちろん、これを読んですぐ目の前のシステムの開発に生きたわけではありません。でも、仕事をしていく中で、何度も「検索エンジンの話と似ているな」みたいなシーンに遭遇することがあって、そのときにこの理論的な背景を知っていたおかげで、「何ができて、何ができないか」という性能限界がすごく明確に分かったんです。理屈が分かっていれば「このやり方では無理だから、別のやり方を考えよう」という判断ができますよね。技術の性能限界を知っていることは、ソフトウェアエンジニアとして最も重要なことの一つだと思います。

 この本の中に、情報検索の基礎モデルとして「確率的言語モデル」というのが出てくるのですが、「線形代数でベクトル空間にドキュメントを置いてきた古典的なモデルを超えて、それを確率的生成モデルで考えることができる……」ということが書いてあります。これがまさに生成AIの最初の部分なんですよね。15年ぐらい前の、ディープラーニング前夜くらいの本なんですけど。つまり生成AIというのは、突然出てきた特異な技術ではなくて、過去から積み上げられてきた体系の上にあるものなんです。

 検索エンジン、情報検索の分野は「コンピューターサイエンスの総合格闘技」みたいなところがあって、アルゴリズムとデータ構造のような話もあるし、線形代数や確率統計の知識も要求されるし、加えて実装もできないといけないから当然プログラミングも必要だし、データベースなども関係してくる。

 この検索エンジンの知識は、はてなにいたときにももちろん役に立ちました。また、一休.comも本質的には検索エンジンなんですよ。「あのホテルを予約できるかどうか」というのは、全部検索エンジンが実現しているんですね。情報検索を理論的に理解できていれば、「どのくらいのことまでできるのか」というまさに性能限界も分かるわけです。

「圧縮」のアルゴリズムはAIにもつながっている

『Managing Gigabytes――Compressing and Indexing Documents and Images』(Ian H. Witten、Alistair Moffat、Timothy C. Bell著、Morgan Kaufmann Publishers)
『Managing Gigabytes――Compressing and Indexing Documents and Images』(Ian H. Witten、Alistair Moffat、Timothy C. Bell著、Morgan Kaufmann Publishers)

 これは、圧縮アルゴリズムについての本です。コンピューターで「データの圧縮」ってあるじゃないですか。みなさんも大きなテキストファイルは圧縮することで保存容量を減らすことができて便利だと思いますよね。圧縮は大規模データを扱うには非常に重要な技術です。そして圧縮は、一見「データのサイズを小さくする」だけに見えるかもしれませんが、 前回 紹介した『記号と再帰』も含めて、話が生成AIにもつながっているんですよ。

 生成AIは「LLMが次に来る言葉の推論をしている」ということはみなさん知っていると思います。人間の脳が本当に同じことをやっているのかはまだ分からないのですが、とにかく次に来る言葉を確率的に推定しているわけです。「リンゴ」と来たら「食べる」が次に来る可能性が高い、とか。自然言語処理やソフトウェアのテクノロジーに関わっているみなさんは、このへんは知っていますよね。

 ですが、この「データ圧縮」や「情報検索」という古典的な分野について勉強していくと、生成AIはこれらからつながっているということがよく分かるんです。先にも述べたとおり生成AIは突然技術的に飛躍したわけではない。圧縮や情報検索といったさまざまな分野の土台の上に乗っている話なんです。

 よく読むと、データ圧縮も生成AIの推論と近いことをやっていることが分かります。前の単語から次の単語が予測できると、次の単語はいらないじゃないですか。さっきの例で言うと「リンゴ」の後に「食べる」が出てくる確率が高いなら、「食べる」は情報としてはなくてもよいことになるから、削減できるんです。つまり統計的な確率分布に基づいて言葉を取り除いていく、データの文脈を見て次に来るものを統計的に処理していくのがデータ圧縮の本質なんですよね。

 それって、生成AIの話とかなり近いじゃないですか。生成AIも大量のデータから学習した内容をパラメータという表現に圧縮して、その圧縮されたデータに基づいて、次に来る言葉を推論している。基礎から積み上げて生成AIをやっている人たちは、そのつながりがよく分かっているんです。これがサイエンスとしてすごく面白くて。

 普段われわれがパソコンでやっている圧縮は、圧縮して伸張するぐらいしかやっていませんが、圧縮アルゴリズムには「圧縮したまま動かす」とか「検索する」、「部分だけを展開する」とかいろんな手法があるんです。最初この本を読み始めたときは「あまり仕事と関係ないかな」と思っていたのですが、情報理論の根底のところで、検索エンジンとか、圧縮とか、生成AIとか、全部がつながっていることに気が付きました。

 最初から「何かの役に立つから」というモチベーションで始めても多分たどり着けないですよね。興味関心とか、好奇心で勉強する分野を決めていくのでいいんだなと思いました。

「Haskell」は意味を記述する美しい言語

『プログラミングHaskell』(Graham Hutton著、山本和彦訳、オーム社)
『プログラミングHaskell』(Graham Hutton著、山本和彦訳、オーム社)

 最後は「Haskell(ハスケル)」の本です。Haskellは関数型プログラミング言語で、一般的に使われている手続き型言語と違うパラダイムで、プログラミングする言語です。仕事で使っている人は多くないですけれど。

 僕も会社のシステムを作るのにはHaskellは使いません。でも、プログラミング言語としての完成度というか、洗練度合いは他の追随を許さないですね。僕は競技プログラミングをやっていますが、そこではHaskellを使っています。競技プログラミングも普通はC++とかPython、あるいは最近だとRustを使う人が多いんですけど、僕はここ3~4年、Haskellで競技プログラミングに取り組んでいます。Haskellで競技プログラミングをやっている人も珍しいですね。数えられる程度しかいないです(笑)。

 説明するのが難しいのですが、僕たちが普段仕事で使っているプログラミング言語は、コンピューターに命令を下すための言語で、「命令型プログラミング言語」と言われるものです。現代のコンピューターアーキテクチャを素直にモデルにしたような言語で、その分「コンピューターに命令する」という点では使いやすい。だから一般のシステム開発には、命令型言語がよく使われています。

 でも、Haskellはそうではなくて、「関数型言語」という名前から何となく想像ができると思いますが、数式を定義するような感覚で、計算を定義することによって、プログラミングを定義するという言語なんです。その分、抽象化能力が高くて、より本質的なプログラム構造を記述することができる。そして自分が書いたプログラムを見て「このコードにどういう意味があるんだろう」と再解釈すると、それまで自分でも分かっていなかった、自分の定義したプログラムの意味が浮き上がってきたりするんです。

 例えば、商品がたくさんあって、それぞれに価格や割引率その他のデータを持っているとします。これから販売価格を計算するなら、命令型言語の場合は順番にループを回して価格を計算して書き換えていくじゃないですか。関数型言語の場合は関数、つまり写像によって「別の数学的空間に写す」という操作で販売価格を求める。何を言ってるか分からないかもしれないですが……。

 そしてHaskellなら「商品というデータ構造を販売価格という値に写す」というように、自分が頭の中で考えている数学的意味そのものをプログラミングとして記述できる。これが本当に美しくて、頭の中で描いている計算イメージを、わざわざ計算機のための操作列に変換することなくそのまま記述できるんです。つまり、命令を考えないで「意味の中に閉じて」問題を考えることができる。

 今日は「人にはおすすめしない」と言いましたけど、Haskellに関してだけは例外的に「やってみるといいよ」と伝えます。Haskellを推すのは僕のエゴですけど、何か課題を見つけて1年か2年Haskellを書き続ければ、間違いなくプログラマーとして飛躍的に成長すると思います。みなさん「Haskellは難しい」とか「どんなことに使えばいいか分からない」と言いますが、僕はHaskellを4~5年やったことで、プログラミングに対するメンタルモデルがまったく別物に変わりました。計算機やプログラムというものが、それまでとはまったく違ったものに見えて、「以前は全然分かってなかったんだな」ということに気が付きました。

取材・文:村上タクタ/写真:尾関祐治(人物)、スタジオキャスパー(書籍)/構成:西 倫英=日経BOOKSユニット第2編集部