自作OSSとしてCommon Lisp用の描画ツールKaiを作っています

f:id:komi1230:20191206222039j:plain

Softbank AI部 Advent Calendar 2019の7日目。

まず始めに、今回一緒にアドベントカレンダーを回していってくれている社員の皆さんと内定者に感謝。

というのも、このSB AI部のアドベントカレンダーの企画を立ち上げたのは自分だからである。

先日より内定してちょこちょこ社員や内定者と交流するイベントに出たりしているのだけれど、縁あってSB AI部(社員の方で構成されている部活)のSlackに招待してもらった。

SB AI部については@kmotohasが書かれた2日目の記事に詳細があるので適宜参照。

ちょうど11月の上旬くらい、ツイッターを見てると色々な会社が社内アドベントカレンダーをやっていて(しかも結構楽しそう)、もしかしてソフトバンクもやっているのかな?と思ってSlackをバーっと確認。

どうも見た感じ特にその手のやりとりは無かったので、randomのチャンネルで質問してみる。

f:id:komi1230:20191206221846p:plain
実は自己紹介以外でSlackで発言するのが初めてだった。

そうすると、社員の方の何人かが面白そう!とかやってみよ!というような反応をしてくださった。

これはイケるやつだ!ということで、勢いでアドベントカレンダーを作成。

最初は2, 3枠しか埋まらず、入社前から早速やらかしたやつかぁ...と心配していたのだけれど、だんだんと勢いが出てきて、最終的にはビッシリ埋まった。

adventar.org

本当に社員の皆さんと内定者には感謝である。

Lisp人工知能

さてさて、前置きはこのくらいにして7日目の記事の本題へ。

AIもとい人工知能は少し前から話題になっていて、ソフトバンクの注力事業であるわけだけど、この人工知能は最近になってポッと出てきたものではなく昔から長いこと研究されている領域だったりする。

では人工知能はいつから研究されているかというと、1950年台に遡り、1956年にAIに関する世界初の国際会議(ダートマス会議)が主催された。

世界で初めて実用デジタルコンピューターが作られたのが1940年代で、世界で初めての高水準プログラミング言語であるFortranができたのが1954年、これらのことを考えてみればコンピューターの黎明期に人工知能という概念が誕生したと言える。

ちなみに余談として、FortranはFormula Translation(式変形)の略で、昔はマシン言語を直接書いてコンピューターに計算をさせていたのだけど、Fortranはより人間に近い言語をマシン言語に変換する役割(いわゆるコンパイラ)として登場し、「これからの時代はプログラミングをやる必要はない!全てコンピューターが自動でやってくれる!」という強烈な宣伝文句とともに一世風靡し、当時では画期的なものであった。 (出典 : 『プログラマーのジレンマ 夢と現実の狭間』スコット・ローゼンバーグ著)

さて、そんな時代の中で開催された国際会議で、ジョン・マッカーシーという数学者が世界で初めて「人工知能」という言葉を定義した。

このジョン・マッカーシー人工知能やコンピューターサイエンスにおいて偉大な貢献をした人であり、実は「人工知能の父」と称されるあのマービン・ミンスキーもこの会議を機にAI研究者を志し、その3年後にはMITでマッカーシーを師事することになった。

さて、この人工知能という言葉を生み出したマッカーシーこそ同時にLispを生んだ人物なのである。(Lisperの間ではマッカーシーLispを"発見した"と言う)

この初めてLispを提案したのがこの論文

マッカーシーの数多くの貢献の中でも特に有名なものとして、現在ほとんどのプログラミング言語で実装されているif文やガベージコレクションなどがある。(実はかつてのFortranにはif文がなくgoto文しかなかった)

if文もガベージコレクションも、高水準プログラミング言語として初めて実装されたのはLispなのである。

これ以外に、マッカーシーはタイムシェアリングシステムというものも提案しており、これは何かというと現在でのアプリケーションサービスプロバイダ、つまりSaaSで、現在流行っているビジネスモデルを半世紀以上前にマッカーシーは実現可能だと提案していた。

...とまあマッカーシーがすごいという話はある程度にしておいて、人工知能の歴史やLispがどのような興隆を経てきたかという話については以下の記事が非常によくまとまっているのでぜひ読んでもらいたい。

tech.dely.jp

人工知能は2回の冬の時代を経て現代でまた興隆を極めているのだけれど、現代の人工知能技術の中核をなす技術であるディープラーニングは膨大な数値計算によって成立している。

かつての人工知能は記号推論によって解決しようとしていたのだが、現実世界でも適用可能な妥当なルールベースを作りこむことが難しいことが分かってきたので、その後は大量のデータからボトムアップ的に学習して自動的に知識表現を獲得してやろうという流れになり、ニューラルネットなどの機械学習手法が発達した。

なので大きな枠組みで見れば現在のディープラーニングも知識をどのように計算機で実現するかという話であり、それを抽象的なレイヤで行うかボトムアップ的に行うかでアプローチが異なるだけだったりして、本質的には変わらなかったりする。

もうPython卒業しようよ

コンピュータの性能向上に伴い、プログラミング言語にはアルゴリズムの表現力と開発効率が要求されてくるようになった。

それにより、今はPythonが最も注目される言語となった。

ただPython単体だとスクリプト型言語のために実行速度が非常に遅く、ディーブラーニングのような膨大な量のパラメータを逐次更新していくようなアルゴリズムに対しては実行が遅すぎるので、ライブラリとして一部の処理をC言語のような高速な言語に実行させることによってアルゴリズムの表現力を保持しつつ実行速度の担保をするような手法が取られるようになってきているのが昨今の流れとなっている。

ここでのライブラリというのがTensorFlowだったりPytorch、Keras、今は亡きTheanoやCaffeなどである。

パッと見だとこれらのアプローチは良さげだと思われるが、例えばエッジコンピューティングのような組み込みなどのものだとPythonを主軸にしたやり方ではメモリを圧迫しすぎてしまうのでプログラムを乗せることができず、結局アルゴリズムの実装しやすさと開発効率を重視したのに最終的にC言語で実装し直すという本末転倒的なことになる。

一応PythonをネイティブコードへコンパイルするCythonというものもあったりするが、結局Python本来が持つアルゴリズムの実装しやすさに制限をかけることになり、結局何がしたかったんだろうという感じになってしまう。

このような考えのもと、機械学習アルゴリズムの社会実装への需要が高まっている昨今でいつまでもディープラーニングアルゴリズムの実装はPythonで実装するしかないというのは少々前時代的という考え方にすら至りうる。

現在ではプログラミング言語も様々な開発が進んでおり、個人的にはJuliaという言語に注目していて、Python以上に柔軟な文法を持ちながら高速である(少なくともPythonの10倍くらい)

このような背景も考えるとPythonに頼り続けるのは限界があると思うし、次の時代を見据えるならPython以外の言語に視野を広げる必要があると思う。

Lispという一つのアプローチ

さて、ここで一つの解決法として自分はLispはアリなのではないかと考えている。

Lispはもともと超絶柔軟な文法を持っており(もはや文法が存在しないと言っていい)、強力な抽象化機構を持っているのでアルゴリズムの表現性という点ではあらゆる言語の中で強力なものである。

柔軟な文法とはどういうことかというと、Lisp自分で構文を定義することができるのである。

例えば、Pythonでは関数を定義する際に

def hoge(x, y):
    return x + y

のように関数を定義することはできるが、このPython本体がもともと持っている関数定義defを自分で定義することはできず、my-defmy-ifのようなオリジナルの構文を作ることはできない。

Lispはマクロという機能を使うことによって自身の構文を定義することができ、言ってしまえばその場で自分オリジナルのプログラミング言語を作ることができる。

具体的に、Lispのマクロを使えばSQLやHTMLなどもLispのコードとして実装することができる。

どの言語を使うかで何を言えるかが変わってくる。

Lispは主に関数型プログラミングパラダイムを採用していて、高階関数ラムダ式をサポートしているため、Lisp本来が持つ柔軟さもあって一つにアルゴリズムを実装するにしてもC言語Lispではコードの量が10倍以上違ってくる。

このようなLispではあるが、速度はどうかというと、C言語並みか場合によってはCより速くなる。

今はLispはあまり有名な言語ではないが、かつてはコンパイラの研究でLispが先頭を走っており、Lispマシンというものも存在したほどであり、昔から高速なプログラミング言語の部類にある。

中には強烈な名言もあり

Cで書くコードの方がCommon Lispで書くより速いって人がいたら、それは彼のCの技量が高すぎるってことだね。

“If you can't outperform C in CL, you're too good at C.” — Eric Naggum

Lispが高速な言語であることを物語っている。

このCより高速なLispのコードを書くことについては以下の深町さんの記事が非常に面白いので参照。

blog.8arrow.org

Lispの高速さを物語るプロダクトとして、この深町さんが実装したWooというHTTPサーバーはあらゆるHTTPサーバーの中でも最高クラスの速度を誇っている。

f:id:komi1230:20191207001656p:plain

Lispがこのような高速さを担保している理由として、OSSSBCLというネイティブコードまでコンパイルする超優秀なコンパイラがあり、これに最適化オプションをつけることによって超高速なコードを書くことができる。(自分はSBCLのコミッター)

最適化に際して、Lispの処理系にはプロファイラという機能がついており、プログラムのどの部分が時間がかかっているかを調べることができるのでボトルネックの発見に役立つ。

そうしてこの時間がかかっているブロックに対して細かく最適化オプションをつけることができ、他のプログラミング言語に比しても最適化を軽快に行うことができる。

この最適化については前に記事を書いた。

komi.hatenadiary.com

このようにLispは速度も高速で柔軟性を持っている言語だが、もう一つ絶対に語っておかなければいけないのがSLIMEという開発支援ツールである。

Lispの特徴として括弧がたくさん現れるが、Lispでは括弧の塊それぞれが一つのソースコードとなっている。

これの何がすごいかというと、ソースコードの一部だけをコンパイルして実行することができる。

f:id:komi1230:20191207003351p:plain

この機能があると、手元で書いたソースコードを即時コンパイルしてその場でテストすることができ、実装からテストまでのサイクルを高速で回せるようになるのである。

以上、Lispは高速で柔軟な文法を持ち強力な開発支援ツールを持ったすごい言語だと言える。

なぜLispは人気がないのか

このようなプログラミング言語として強力過ぎる魅力を持った言語であるのに、なぜLispはユーザーが少なく人気がないのか。

これに関してはさっぱりわからない。

自分はLispを書き始めて数年経つが、特に文句はないし、むしろC言語PythonJavaScriptなどの他の言語を触るたびに「なぜLispのような機能がないのか」「なぜLispより圧倒的に遅いのか」とイライラさえする。

もっとLispは評価されるべきだしLisp界隈が盛り上がっていくべきだと思っている。

ただ一点、指摘することがあるとすれば、ライブラリの開発が全体として勢いがないというのはある。

これはLispユーザーが少ないことによる副次的な影響なのだが、ライブラリの開発があまり活発に行われていないために死んでしまっているようなライブラリも数少なく、ソースコード自体はバリバリ現役でもドキュメントが古すぎて存在しない(もしくは埋もれてしまっている)ということがある。

Lispのこれからのために

そのようなLispであるが、個人的には最近どんどん勢いが上がっている気がする。

先述の深町さんがCommon LispでWeb系ライブラリを作りまくってLisp × Webの雪原を踏み荒らしまくった結果、Lispユーザーがグッと増えたような気がする。

それを見て、自分は自分も得意分野を盛り上げて行こうと思うようになった。

先日もIBMでAIリサーチャーをやっているMasataro AraiさんからNumclというライブラリを一緒に開発していかないかとお誘いいただいた。

これはPythonのNumpyにある機能をCommon Lispライクに実装しようというプロジェクトで、自分は機械学習系・数値計算系の人間なので、このようなプロジェクトは非常にワクワクしている。

さて、数値計算機械学習系のプロダクトを開発するにあたって、何かとデータを可視化させるツールというのは必要になる。

一応Common LispにはCL-Plotのような可視化ツールは存在するが、だいたいが2次元プロットで、3次元プロットや散布図、ヒストグラム、ヒートマップのような機能はない。

ということでMatplotlibのようなプロッターをOSSとして自分で作ることにした。

github.com

名前はKaiとし、ハワイ語で海という意味を持つ。

現在まだ開発途中であるが、すでに2次元プロット程度ならできるようになっている。

f:id:komi1230:20191207005216p:plain
Kaiでプロットしてみた図

まだ依存関係を記述するファイルなどを整えていないのでプロダクトとしてしっかりリリースはできていないが、ライブラリとしての体裁が整ったらまた追って正式にリリースの報告を出そうと思っている。

自分はLispを愛しているが、これからどんどん盛り上がっていけるように自分にできるコミットをどんどんやっていこうと思う。

これからLispの時代が来るように、一つ一つできることを積み上げていこうと思う。

終わりに

Softbank AI部のアドベントカレンダーの記事だったが、結果的にただのLispの宣伝になってしまった感がある。

ただ、本当に自分はこれからのAI系プロダクトではLispは一つのアプローチになると信じているので、これからもコミットしていこうと思う。

それではお疲れ様でした。

興味を持った人に読んでほしいもの

Lispをちょっと始めてみようかなという人向けの記事。

qiita.com

Common Lispの勉強で、入門として非常に良い本。

www.oreilly.co.jp

Y Combinatorの設立者でありLisp界のゴッドファーザーポール・グレアムのエッセイ。

Amazonのリンク

gist.github.com