見出し画像

文化的特異点の到来 / Claude3.7-coder使ってみた

ずっとClaudeが好きだったのに、最近o3-miniに浮気していた。
ところがClaudeが帰ってきた!3.7という控え目なバージョンナンバーとともに。

特筆すべきはダントツのコーディング能力

もうええでしょう

o3-miniとの比較がないのでこれだけで一概には言えないが、そもそもo1-proの段階で僕の3Dコーディング能力を超えていたので、どのくらい凄いものか探ってみることにした。

Memeplexでアルファテスト中のコーディング機能を試験的に対応させた。「/claude」をつけるとClaude-3.7でコードを書いてくれる。

Claude-3.7が吐き出すコードは結構癖があるなという感じだが、効果は抜群。想像することも難しかったような4Dマンデルブロ集合を一発で書いてくれた。しかもリアルタイム処理で。

しかしもはや4Dマンデルブロなど書いたことがない俺には、これが正しいのかどうかもわからん。しかし、明らかに四次元的な動きをしているので、なんらかの4Dフラクタル集合を作っていることは確かなようだ。Claude-3.7が吐き出したコードを読んで勉強する。悔しいことに、綺麗に書けてる。

   // 4次元マンデルブロ集合の計算
    vec4 mandelbulb(vec3 pos) {
      vec3 z = pos;
      float dr = 1.0;
      float r = 0.0;
      float power = 8.0 + 2.0 * sin(time * 0.2);
      int iterations = 0;
      int maxIterations = 15;

      // 4次元回転のためのパラメータ
      float w = sin(time * 0.1) * 0.5;
      float cw = cos(time * 0.3);
      float sw = sin(time * 0.3);

      for (int i = 0; i < 100; i++) {
        if (i >= maxIterations) break;

        iterations = i;
        r = length(z);
        if (r > 2.0) break;

        // 4次元回転の適用
        vec3 zRot = z;
        zRot.x = z.x * cw - z.y * sw;
        zRot.y = z.x * sw + z.y * cw;
        z = zRot;

        // 極座標に変換
        float theta = acos(z.z / r);
        float phi = atan(z.y, z.x);
        dr = pow(r, power - 1.0) * power * dr + 1.0;

        // 累乗計算
        float zr = pow(r, power);
        theta *= power;
        phi *= power;

        // 直交座標に戻す
        z = zr * vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));

        // 4次元の要素を加算
        z += pos * (1.0 + w * sin(time + float(i) * 0.1));
      }

      float dst = 0.5 * log(r) * r / dr;
      vec3 color = getColorFromIterations(iterations, maxIterations);
      return vec4(color, dst);
    }

コードの本体はWebGLのシェーダーで、これだけみると恐ろしくシンプルだ。優れた数式は同時に美しさも兼ね備えるという点で、非常に見所がある。

曲座標に変換してから直交座標に戻しているあたりの理由がよくわからないが、これは3Dマンデルブロ集合(Mandelbulb)を拡張したからだろう。

これから世の中はどこへ向かっていくのだろうか。

よく、分野外の人から「コンピュータのことならなんでもわかるんでしょ」と言われることがあるが、当然そんなことはない。

自分が得意分野であるはずの3Dプログラミングでさえ、ある一定以上の複雑さになると、直感的に考えることが難しくなり、ステップ・バイ・ステップで薄氷の上を踏みながら渡るような計算を何日も重ねないとクリアできないようなコーディングをずっと続けてきた。

もしも4Dマンデルブロ集合をWebGLでゼロから書こうとしたら、真面目にやっても一ヶ月くらいはかかっただろう。もっとかもしれない。

それが1分も経たずに出てきてしまう。怖い。怖いわこいつ。

そしてもうこいつに「どんな無茶を言えるか」という新しいゲームが始まっている。

やっぱりプログラマーだから、先入観から「これは無理だろう」と萎縮してしまって新しいことが言えなくなったりする。

けど、素人の人はむしろ「ポケモン作って」とか言えばできるのか、とか、「Age of Empire作って」と言えばできるのかとか、もうそのレベルのことを考え始めている。そして、そう言われると「まあ一発では無理でも段階を踏めば可能かもしれない」と思えてくる瞬間も確かにある。

例えば難易度をどう捉えるとか、抽象度の高いオーダーだったら、最初に設計図を書いて、それをどう扱うようにするかとか。そういうことが大事になる。

こうなると、大規模言語モデルそのものよりも、大規模言語モデルの「使い方」の方が重要になってくるので、これから先、CursorやWindsurfのような開発支援ツールや、今僕がMemeplexでアルファテストしているような、簡易な開発環境は設計の自由度と重要度がどんどん増していくだろう。

単に内部でLLMを呼び出すのではなく、どういうLLMをどのように組み合わせたらユーザーにとって最適なものが作れるか。抽象度の高い質問に対して行間を埋めるようなプログラムをどう作るかということがむしろ重要になるに違いない。

単一のモデルが全てを解決することはほとんどあり得ないので、モデルの組み合わせが大事になってくる。ここには言語だけでなく、画像生成モデルや画像理解モデル、動画生成モデルも渾然一体となって入ってくるだろう。

今、AIを前提とした新しいプログラミングパラダイムが必要になってきている。

かつて僕がタブレットを独自開発してまでやりたかったことは、「人々の想像力を直接拡張する」ことだ。プログラミングできなかった人が、できるようになれば、そういう人が一人でも増えていけば、世の中はもっと良くなる。

そのためには、二つのアプローチが考えられた。
まず、ソフトウェア工学とアーキテクチャの歴史を振り返ってみよう。

人とコンピュータの共生の歩み

最初の最初、人は機械を使うためにマシン語を使うしかなかった。
アーキテクチャはCPUのみであり、人は複雑なメモリ管理や外部機器との通信といったややこしいことも自分で処理しなければならなかった。

そもそもこの時代の人々は二進数を直接入力していた。

スイッチで二進数を直接入力するのだってかなり後になってからだ

やがて、BIOSが開発され、ごく基本的な入出力についてプログラマは考えなくて良くなった。また、16進数や2進数を直接入力していた機械語の時代から、簡単な英語で擬似的なプログラムを書くと、自動的に機械語に翻訳してくれるアセンブラが開発され、プログラマの負担はまた少し減った。

当時のプログラマを悩ませていたメモリ管理は専用のハードウェアが開発され、MMU(メモリ管理ユニット)などと呼ばれるようになった。これでさらにプログラマの心配事は減った。

そして専門のプログラマでなくても、例えば科学者が扱う方程式(Formula)を入力すると、それをマシン語に翻訳(Transration)してくれる高級言語であるFORTRANが生まれた。また同時期に、1930年代(コンピュータが発明される以前である)に考案されたラムダ計算をリストとして表現してコンピュータで実際に計算するLISP(LIst Processor)も生まれ、プログラマの間口はまた少し広がった。

FORTRANをベースにさらに簡略化したBASICは、最初の起爆剤としてプログラマ人口を世界中に増やした。また、帳票計算用のCOBOLという言語も生まれた。

同時期に、科学技術計算に必要な浮動小数点の計算を専用に行う浮動小数点演算コプロセッサが開発される。

しかし、FORTRANやCOBOLといった言語は、一定以上の複雑さを持つようになると途端に管理が難しくなり、バグはプログラマたちだけでなく経営者までをも悩ませるようになった。

そこを打開するために、よりバグが少なく保守性の高いコードが書ける構造化言語という概念が生まれ、Modula-2やC言語が生まれた。C言語はおそらく人間が許容できる最低限度の抽象化を実現し、C言語の誕生と普及によって、世界は見たこともない人たちの力を借りてより複雑なプログラムを簡単に書けるようになった。

機械語の時代は、「モジュール」とは物理的な部品だった

C言語のような構造化された高級言語の出現を前提として、マシン語を直接プログラマが扱わなくなったのでコンパイラによる最適化を前提としてより高速に動作するRISCプロセッサが生まれた。

構造化をさらに進めた結果、より高度な分業が必要になり、オブジェクト指向が生まれた。プログラム・モジュールの抽象度をより高め、差分プログラミングを実現した。もうプログラマは、コンピュータの中で起きてる全てのことに責任を持つ必要はない。自分の担当したモジュールの責任だけ持てば良いのである。

この頃、さらに高度化する計算に対応するため、複数のデータを同時に処理するSIMD(単一命令多数データ;Single Instruction Multiple Data)がハードウェア・アーキテクチャに追加された。

圧縮された動画や音声、3Dグラフィックスという複雑な計算を一手に引き受けるこのSIMDアーキテクチャは、さらに発展してGPU(グラフィックス・プロセッシング・ユニット)に進化した。GPUは高まるユーザーの欲求に応えるためにそれまでのハードウェア・アーキテクチャとは異なる方向へ進化していく。特にWindowsを高速に動かすためにGPUが必要とされ、次にゲームを高速に動かすためにGPUの需要は爆増した。

この時代になると、プログラミングが簡単になってプログラマの人口が増大する一方、GPUが扱うような複雑な計算を理解できるプログラマの相対数は激減し、市場のニーズと複雑なコードが書けるプログラマの数が合わなくなってきた。

そこで、もはや複雑なことを考えなくてもプログラムが作れるようにプログラムの大枠をごく少数のエリートが作り、その他大勢のプログラマがわずかな差分だけを書くという、フレームワークやゲームエンジンが大流行した。この流れは現在にも続いている。

激しいゲーム競争によって高度化したGPUの計算能力は、グラフィックス以外のより一般的な目的(GP;General Purpose)にも使われるようになり、GPGPUと呼ばれた。

当初のGPGPUでは、スーパーコンピュータで処理していたような科学計算や物理計算が専ら行われたが、その中で結果的に最も歴史的インパクトを与えたのは、ニューラルネットの復興だった。

プログラムは益々簡単になり、サーバーレスやノーコードといった、複雑なプログラミングやノウハウを必要としない環境が構築されつつある。

そして今、ハードウェア・アーキテクチャにLLMが加わる。

一見するとソフトウェアで実現されているニューラルネットワークとLLMを「ハードウェア・アーキテクチャ」に含めるのを奇妙だと思われる人もいるだろうが、そもそもメモリ管理ユニットも浮動小数点演算もまず最初にソフトウェアで実現されていて、それからハードウェアになったという経緯がある。GPUは事実上ニューラルネットの専用ハードの様相だし、GroqのようなLLMに特化したハードウェアも出てきていることを考えると、ソフトウェア開発者からしたらブラックボックス化した部品という意味で、ニューラルネットもLLMもハードウェア・アーキテクチャに含めて良い。

という歴史を振り返ると、今まさに特異点が迫っているのである。
つまりそれは、「特別な訓練を受けなくても自分の考えをプログラムとして表現できる時代」の到来である。

これは「技術的特異点」ではないかもしれないが、人類にとっての「文化的特異点」になることは間違いない。