どうも、マイクです。おはようございます。
時刻は朝7時を少し回ったところ、2025年12月23日、火曜日。
今朝も「zenncast」、ゆるっと楽しくお届けしていきます。
この番組では、エンジニアのみなさんと一緒に、Zennでいま話題になっているトレンド記事をチェックしていきます。通勤のお供に、朝のコーヒーのお供に、ながら聞きでOKなので、気楽にお付き合いください。
今日は、Zennのトレンドから全部で5本の記事をご紹介していきます。どれも技術的にはかなりディープなんですが、ラジオなので、できるだけ噛み砕いて「どこがおもしろいのか」「どんな現場で役に立ちそうか」を中心にお話ししていきますね。
ではまず1本目。タイトルは「LLMのCUDAカーネルを自作しよう!」。
これ、ガチでGPUと仲良くなりたい人向けの記事です。
普段PyTorchを使っていると、「GPUでいい感じに速くしてくれてありがとう!」っていうブラックボックス的なありがたさがありますよね。でもこの記事では、その「いい感じ」の中身に踏み込んで、GPT‑2モデルを題材に、CUDAカーネルをスクラッチで自作していきます。
やっていることがすごくて、Linear、GELU、Dropout、LayerNormの代わりになるDyT、Embedding、Scaled Dot Product Attentionみたいな、GPT‑2の主要なブロックを、forwardもbackwardも含めて、C++とCUDAでガチ書きしていきます。さらにCrossEntropyLossとAdamWオプティマイザまで自作するという、ほぼ「俺PyTorch」状態ですね。
単なる写経じゃなくて、ちゃんと計算グラフと連鎖律に基づいて勾配計算を導出していくので、「なぜこの勾配になるのか」が腹落ちしやすい構成になっています。で、作ったカーネルをCMakeで共有ライブラリにして、pybindとLibtorch経由でPythonから呼び出すところまで一通り載っているので、「自作CUDAをPyTorchとつなぐ」実践的な手順もわかる。
最終的には、36Mパラメータ規模の日本語GPT‑2を学習させて、純正PyTorch版とlossの推移を比べて、「ちゃんと同じように学習できてるね」という検証までしているのもポイントです。まだ速度やメモリ効率では本家に負けているけど、「なぜPyTorchがあれだけ速いのか」「どこがボトルネックになりがちなのか」が肌感でわかるようになる記事。
ディープラーニングを「ライブラリ利用者」から一歩進んで「中身を理解したい」人には、めちゃくちゃ刺さる内容だと思います。
。 。 。 。
続いて2本目。タイトルは「『Skills?MCP?インストラクション?』仕組みからわかる GitHub Copilot のカスタマイズ戦略ガイド」。
GitHub Copilot、Agent Modeが出てきてから、機能名がいろいろ増えすぎて、「結局何をどう使えばいいの?」ってなってる人、多いと思うんですよね。この記事は、そのモヤモヤを整理してくれる、「Copilot設計図」みたいな内容です。
軸になっているのは、「LLMは結局、メッセージリスト=コンテキストをどう組むかの勝負だよね」という視点。
そのうえで、
・カスタムインストラクションは「常に効き続ける全体方針」
・カスタムエージェントは「あるタスクに特化した、指示+ツールセットのパッケージ」
・サブエージェントは「コンテキストを分けて、副業みたいなタスクをこなす小さなエージェント」
・MCPは「外の世界とつなぐツール箱。ただし増やしすぎるとモデルが迷う」
・Agent Skillsは「必要になったら読み込む、再利用可能なスキル定義へのポインタ」
・プロンプトファイルは「スラッシュコマンドで呼べる、エージェント起動の入口」
っていう整理をしてくれます。
ポイントは、「とりあえず全部盛り」じゃなくて、役割を分けて設計しましょうという提案。タスク特化したいならカスタムエージェントを軸にして、組織全体の開発ルールはカスタムインストラクションに書く。よく使う手順やナレッジはAgent Skillsとして再利用し、外部サービスへの接続はMCP、そしてそれらを簡単に呼び出せるようにするのがプロンプトファイル、という整理ですね。
Copilotを「なんとなくの相棒」から「設計されたチームメンバー」に進化させたい人にとって、実務目線でかなり役に立つ内容になっています。
。 。 。 。
では3本目。タイトルは「50人以上の開発者が日々使用する10万commitオーバーのGitHubリポジトリを分離した」。
これは、巨大Railsモノレポをどうやって安全に分離したか、というリアルなドキュメントです。10万コミット超え、2プロダクト、2組織、50名以上が同じリポジトリを使っていたという、なかなかヘビーな状況からスタートします。
時間が経つにつれて、影響範囲が広すぎて変更にビクビクするようになったり、共有コードがプロダクトごとに微妙に分岐したり、CI時間とコストが膨らんだり、デプロイ調整が衝突したりと、「モノレポのつらみフルコース」になっていくんですね。障害発生時の切り分けも難しくて、組織全体の認知負荷が限界に達したと。
そこでコンウェイの法則、つまり「組織構造はシステム構造に反映されるよね」という視点から、リポジトリを分離する決断をします。ただ、完全に分けられるわけではなく、一部はDBを共有したままなので、モデルを両リポジトリに複製したり、Dangerでレビュワーを自動アサインしたり、スキーマ同期用のGitHub Actionsを用意したりと、現実的な工夫が入ってきます。
CI/CD周りも、CircleCIの設定、Secrets、ラベル運用まで含めて両プロダクトで全面的に見直し。実際の分離作業は`git clone/push --mirror`で履歴ごと移し替えたうえで、PRのrefsをどうするか、pushサイズ上限、デフォルトブランチの変更、移行中にCIが動かないようにする工夫など、細かい注意点まできっちり押さえています。結果として、週末に本番一発移行して無事故で終えられた、というのもすごい。
ここをゴールではなく「大きな技術的負債返済のスタート」と位置付けていて、組織とシステムの整合性をこれからも取り続けていく、という締めくくりも印象的です。モノレポで悩んでいるチームには、かなり参考になる現場レポートだと思います。
。 。 。 。
4本目いきましょう。タイトルは「TanStack DBってなに? —— TanStack Queryと比較しながら理解する『クライアントDB』という選択」。
フロントエンド界隈でTanStack Queryはだいぶおなじみになってきましたが、そこに新しく出てきたのがTanStack DB。「何が違うの?」ってなりがちなんですが、この記事はそこを整理してくれます。
TanStack Queryはあくまで「サーバーからデータを取ってくる係」。一方、TanStack DBは「クライアント側でデータをためておいて、SQLライクなクエリで扱うためのレイヤー」です。サーバーから取ってきたデータを「コレクション」としてクライアント内に保持しておいて、`useLiveQuery`という仕組みで、filter、sort、joinを含む問い合わせ結果をライブに再評価してくれます。
つまり、UIが欲しがっている形そのものをクエリとして書けて、その結果にUIが自動で追従してくれるイメージですね。insertやupdateも、「DBに対して操作を書く」感じで書くと、UI側が勝手にいい感じに更新される。しかも楽観的更新とロールバックも設計に組み込まれているので、「まずUIを更新して、失敗したら戻す」といったパターンも扱いやすい。
joinを含む複雑なクエリでも、必要なデータだけをサーバーと同期するように賢く動くので、「画面ごとに微妙に違うデータ構造が欲しい」とか「複数のリストをまたいだ集計をしたい」といった場面で威力を発揮します。逆に、単純なCRUDだけなら、TanStack Queryだけで十分なケースも多いよね、という冷静な線引きもされているのが良いところ。
フロント側で状態管理とデータ整形に苦しんでいるチームには、「クライアントDB」という選択肢を考えるきっかけになる記事です。
。 。 。 。
そして5本目。タイトルは「Python のコンパイラを作りたい #9 - MLIR の導入と最適化」。
これは、自作の「Python風言語」Lythonのコンパイラ設計を、MLIRベースに作り替えた話です。かなり理論寄りなんですが、「なぜその設計を選んだのか」が丁寧に説明されていておもしろいです。
従来は、いきなりLLVM IRを直接吐いていたところを、まずMLIR上にPython Dialectを定義して、高水準の意味を残したまま最適化してからLLVMへ落とす構成に変更しています。これによって、「Pythonっぽさ」を保ったまま、より賢い最適化ができるようになる。
設計の肝になっているのが、「Boxedな世界」と「Unboxedな世界」の分離です。CPython互換風のPyObjectたちが暮らす世界と、C言語っぽいプリミティブ型だけの世界をきっちり分けて、暗黙の変換は禁止。boxing/unboxingは必ず明示的にやる、というルールにしています。これを様相論理の「世界」になぞらえて説明しているのが、かなり思想強めで面白いところ。
Unboxed側では、`@native`アノテーションを付けた関数は完全にプリミティブ世界に閉じていて、C ABI対応&PyObject禁止をMLIRのverifierで機械的に保証するようになっています。一方、Boxed側では、量的型理論にインスパイアされた参照カウントの挿入・削減パスを用意していて、LLVMの最適化と組み合わせることで、INC/DECREFの回数を大幅に減らすことに成功しています。
具体的には、フィボナッチ関数の例で、CPython相当だと約22回のINC/DECREFが発生するところを、9回まで減らせた。その結果、JIT実行でCPythonの約2.5倍、さらにプリミティブ版だと約22倍の速度が出た、というかなりパンチのある数字も出ています。
実装自体はC++でMLIR/LLVMのAPIをたたきつつ、Pythonのフロントエンドを組み合わせていて、すでにAOT/JIT、vectorcall、基本的なクラス機能などが動いているとのこと。今後は、ベクトルや行列といった高階プリミティブ、WASM/WASI、クロスコンパイル、abi3互換レイヤと、かなり野心的なロードマップも語られています。
Pythonが好きでコンパイラにも興味ある人には、たまらない連載ですね。
。 。 。 。
というわけで、今日は全部で5本ご紹介しました。
GPUの深淵に潜っていくCUDAカーネル自作のお話、Copilot Agentをどう設計していくかというコンテキストエンジニアリングの話、巨大モノレポを安全に分離した現場レポート、フロントエンドの新しい選択肢であるTanStack DB、そしてMLIRを使ったPython風言語コンパイラの最適化ストーリーまで、かなり盛りだくさんでしたね。
気になった記事があれば、詳しい内容は番組のショーノートにまとめてありますので、あとでぜひじっくり読んでみてください。通勤中に聞いている方は、職場に着いたらメモ代わりにチェックしてもらえると嬉しいです。
「zenncast」では、番組の感想や「こんなテーマを取り上げてほしい」といったリクエストも随時募集しています。普段どんな開発をしているのか、どの記事が刺さったか、ゆるい一言でも大歓迎なので、ぜひ送ってください。
それでは、そろそろお別れの時間です。
今日も一日、無理しすぎず、いいコード書いていきましょう。
お相手はマイクでした。また次回の「zenncast」でお会いしましょう。いってらっしゃい!