これは、私がまだ高校生だったときに始めた話です。
特別な研究室にいたわけでも、誰かに教わったわけでもありません。放課後の自室で、一台のPCと向き合いながら「これは不便だな」と思ったことを、ひとつずつ自分の手で解いていった。その積み重ねが、いつのまにか米国の著名なOSSプロジェクトの公式リリースノートに、私のハンドルネームを残すことになりました。
これまでのIT経験
本題に入る前に、これまで取り組んできた主な活動・実績を簡単にまとめておきます。
- Hugging Face Diffusers v0.33.0 の「Significant Community Contributions(注目すべきコミュニティ貢献)」に選出
- Hugging Face Diffusers 公式ドキュメントに、自作ライブラリ auto_diffusers がコミュニティライブラリとして掲載
- anime_seg(イラスト向けセグメンテーション)を公開 ― 公開2日で 1,100+ ダウンロード、PyPI 累計 11,500+ ダウンロード
- DevFest 2025(Google Developer Group 主催)に登壇 ― MediaPipe を用いたイラストのセグメンテーションについて発表
- Kmetric Inc. でのインターン にて、Golang × AWS Lambda × Terraform × DynamoDB によるサーバレス構成を構築
「面倒くさい」から、すべては始まった
高校時代、私は画像生成AIに夢中になっていました。Stable Diffusion を自分のPCやGoogle Colab で動かしては、どんな絵が出てくるのかを延々と試す日々。けれど、夢中になればなるほど、ある「面倒くささ」が気になるようになりました。
使いたいモデルを見つけるたびに、配布ページを探し、URL をコピーし、ファイルをダウンロードして、コードのパイプラインに読み込む。その繰り返しです。Hugging Face や Civitai には、世界中の人が公開した魅力的なモデルが何千とあるのに、ひとつ試すまでの手間が大きすぎる。「キーワードで検索して、そのまま読み込めたらいいのに」と、何度も思いました。
当時の私は、情報科学を体系的に学んだわけではありません。それでも、「不便だと感じたなら、誰かが作ってくれるのを待つより、自分で作ってしまえばいい」。そう考えたのが、すべての出発点でした。今振り返ると、この素朴な動機こそが、その後の数年を貫く一本の軸になっていたように思います。
前身 diffusers_in_Colab から、汎用ライブラリ auto_diffusers へ
最初に形にしたのが diffusers_in_Colab でした。Google Colab 上でモデル名を打つだけで、Hugging Face と Civitai を横断して検索し、見つかったモデルから自動でパイプラインを組み立てる。そんな小さなツールです。最初は完全に自分専用のつもりでした。自分の「面倒くさい」が消えれば、それで十分だと思っていたのです。
ところが、使い込むほどに、もうひとつの限界が見えてきました。diffusers_in_Colab は、その名のとおり Google Colab のノートブック上で動くことを前提にした作りで、どうしてもその環境に縛られてしまう。便利なのに、Colab を使わない人には届かないのです。同じ不便を感じている人は世界中にいるはずなのに、これではもったいない。だったら、Colab への依存をきっぱり断ち切って、誰でも `pip install` するだけで、どんな環境からでも呼び出せる「ライブラリ」に作り変えよう。
そうして一から作り直したのが auto_diffusers です。設計の軸は一貫して「面倒くさいを消す」こと。数行のコードを書くだけで、キーワードによるモデル検索から、画像生成パイプラインの自動構築、さらには LoRA や Textual Inversion といった追加要素の読み込みまでが完結する。利用者が本来やりたいこと(絵を生成すること)以外の雑事を、できるだけ肩代わりする道具を目指しました。
実際の使い方は、たとえばこれだけです。
pip install auto_diffusersfrom auto_diffusers import EasyPipelineForText2Image
# キーワードで検索し、そのままパイプライン化(Hugging Face / Civitai)
pipe = EasyPipelineForText2Image.from_huggingface("model_name_or_keyword").to("cuda")
image = pipe("cat").images[0]
image.save("cat.png")
# LoRA や Textual Inversion も、名前を渡すだけで自動ロード
pipe.auto_load_lora_weights("Detail Tweaker")
pipe.auto_load_textual_inversion("EasyNegative", token="EasyNegative")
この「シンプルさ」は、実は意識して選び取ったものでした。前身の diffusers_in_Colab には、モデルの選び方が二通りあったのです。検索結果から最もダウンロード数の多いものを自動で選ぶモードと、番号を入力して利用者自身が選ぶモードがありました。
auto_diffusers を作るとき、私はこの後者、つまり対話による手動選択を思い切って削除しました。diffusers や transformers のようなライブラリでは、処理の途中で input() を使ってユーザーに問いかける作法は、まず使われません。コードの規約やお作法を読み込むほど、「ここは削るべきだ」と感じたのです。せっかく作った機能を捨てるのは迷いましたが、既定で最有力の候補(検索結果の先頭。Civitai ではダウンロード数の多い順)を自動で選び、番号で指定したい人には対話ではなく candidate_index という引数を渡す。そう割り切って、機能を「足す」のではなく「削って」シンプルにしました。
API の形そのものも、既存のライブラリに倣いました。EasyPipelineForText2Image.from_huggingface("search_word").to("cuda")` という書き味は、diffusers の Pipeline.from_pretrained(...).to("cuda") や単一ファイル読み込みの作法をなぞったもの。世界中の人が、説明書を読まなくても直感的に使えるように、既存の「お作法」にそろえることを優先しました。
auto_diffusers がさりげなく引き受けている仕事のひとつに、「読み込み方法の違いを吸収する」ことがあります。実は公式の diffusers でも、モデルの読み込みは大きく二系統に分かれています。整った形式で配布されたモデルを読む from_pretrained と、Civitai のように一つのファイルにまとまったチェックポイントを読む from_single_file です。
from diffusers import StableDiffusionPipeline
StableDiffusionPipeline.from_pretrained("Lykon/dreamshaper-8") # 整形済みリポジトリ
StableDiffusionPipeline.from_single_file("model.safetensors") # 単一ファイル(Civitai 等)
auto_diffusers は、この違いを最初から内部で吸収するように作ってあります。入力が単一ファイルなのかリポジトリなのかを判定し、読み込み方法を自動で振り分けているのです。
# auto_diffusers の内部(pipeline_easy.py)
if os.path.isfile(keyword):
status["loading_method"] = "from_single_file" # 単一ファイル
elif os.path.isdir(keyword):
status["loading_method"] = "from_pretrained" # 整形済みリポジトリ
...
if checkpoint_status.loading_method == "from_single_file":
pipeline = load_pipeline_from_single_file(...)
else:
pipeline = cls.from_pretrained(checkpoint_path, **kwargs)
利用者は、モデルがどんな形式で、どこに置かれているかを意識する必要がありません。ただ検索ワードを渡すだけです。
おもしろいのは、この「二つの読み込み方法の一本化」が、のちに本家 diffusers でも議論になったことです。私はこの統合を本体にも持ち込めないかと提案しました(PR #10208)。けれどメンテナの yiyixuxu さんから返ってきたのは、次の言葉でした。
"we are not 100% about if we are going to unify these two methods yet. We will not be able to merge PR at the moment."
(この二つを統合するかどうかは、まだ私たち自身も固まっていない。今はマージできない)
本家のメンテナですら、踏み切るかどうかを保留にする。それくらい厄介なテーマを、自分の小さな道具の中では、利用者に一切意識させずに片づけていた。そのことに後から気づいて、少し誇らしくなりました。
個人のノートブックを、世界の誰かが使うライブラリに作り替える。それは、ただ動けばいいコードと、他人に使われることを前提にしたコードとが、まったく別物だと気づく過程でもありました。
とはいえ、ここに至る道のりは、決して順調などとは言えませんでした。当時の私はまだ高校生で、隣でコードを教えてくれる先輩も、メンターもいません。生成AIに頼ろうにも、当時の GPT-3 はコードの精度がまるで頼りにならず、提案をそのまま使えば、冗談抜きでほぼ一行ごとにエラーが出る始末。結局、ほとんどを自分の手で書くしかありませんでした。return のインデントをたった一段間違えていただけで、処理が走らないまま静かに止まってしまう。UnboundLocalError のたった一行に、半日頭を抱える。今なら一瞬で直せるようなことに、当時の私は本気で心が折れそうになっていました。それでも、毎日と言っても大げさではないほど画面とにらめっこを続け、その日々を何年も積み重ねました。動かなかったコードが、ある日すっと動く。その小さな快感だけを頼りに、なんとか手を止めずにいられたのだと思います。
本家 Hugging Face への挑戦と、思わぬ転機
auto_diffusers を育てる一方で、私はもうひとつの目標を抱くようになりました。「本家の Hugging Face Diffusers そのものにも、貢献できないか」。Diffusers は、画像・動画生成の分野で世界中の開発者・研究者が使う、デファクトスタンダードのライブラリです。そこに自分のコードが入れば、もっと多くの人の役に立てる。
慣れない英語で、私が本家に最初に出した Pull Request は、ささやかなバグ修正でした(PR #8452、2024年6月)。結局これはマージには至りませんでしたが、世界中が使うコードに自分が手を入れ、提案できること自体が、たまらなく刺激的でした。
思えば、海外の開発者と自分から主体的に技術的なやり取りをするのは、これが初めての経験でした。返事が来るのが怖くもあり、けれどそれ以上に、いったいどんな反応が返ってくるのかが楽しみで仕方ありませんでした。GitHub から通知が届いていないか、一日に何度も何度も確かめていたのを覚えています。その一方で、相手に失礼があってはいけないと、たった一通のメッセージを書くのに10分も20分もかけ、何度も英文を読み返していました。
続いて同年8月に出した (PR #9068) は、もっと踏み込んだ提案でした。生成画像の安全性フィルタ(safety_checker)の強度を細かく調整できるようにするもので、単なる思いつきではありません。自分で生成した 8,000 枚もの画像を分析し、誤検知を減らすための最適な閾値を統計的に割り出した、地道な研究です。
それまで実質オン・オフの二択だった安全フィルタを、WEAK から MAX まで段階的に、あるいは数値で指定できるようにしたものです。
pipe.safety_checker_level("STRONG") # 'WEAK'〜'MAX'、数値での指定も可能
pipe.filter_level() # 現在の強度を確認
メンテナの hlky さんからは "Awesome research, thank you @suzukimain!"(素晴らしい研究だ、ありがとう!)という言葉をもらいました。この提案は今もオープンなまま残っていますが、自分の取り組みが「研究」として世界の第一線の開発者に認められたことは、大きな自信になりました。
本家への入り口として最初に出したのは、モデル検索機能を diffusers の コミュニティ向けサンプルとして加える (PR #9986 2024年11月) でした。いきなり本体に手を入れるのではなく、まずはコミュニティの実装として提案したものです。メンテナからも "Really cool and convenient functionality"(とても便利でクールな機能だ)と、好意的な反応をもらえました。
ところが、その #9986 に、あるコミュニティの開発者からこんな声が寄せられます。「コアの AutoPipeline から直接呼べるようにできない? AutoPipeline.from_civitai(...) のように」。背中を押された私は、それならばと、同じ機能をdiffusers の中核(AutoPipeline 本体) に組み込む PR #10006 を新たに出しました。検索の仕組みは、最初から model_type 引数を変えるだけで複数のタスクに対応できるよう設計してあり、あとから機能を足していけることも見据えていました。先見の明、というと大げさですが、拡張の余地をあらかじめ用意しておいたつもりでした。
実装は別のレビュアーから "pretty clean"(とてもきれいだ)と評価され、反応も上々。今度も通るはずだと思っていました。ところが、これはコアには入れられない、と告げられます。理由は技術の外側にありました。私のライブラリは Hugging Face だけでなく、Civitai(Hugging Face Hub の競合にあたるモデル配布プラットフォーム)も検索の対象にしている。先ほどの開発者は、議論の中でこうも漏らしていました。"assuming huggingface doesnt want to support a competitor even if it benefits the user"(ユーザーに利があっても、Hugging Face は競合をサポートしたくないんだろうね)と。期待していただけに、正直ひどく落胆しました。
ここで私は、大切なことに気づきました。どれだけ技術的に優れていても、ユーザーにとって便利でも、ビジネスや競合といった経営的な側面と噛み合わなければ、「本体」には入らない。 OSS は純粋な技術だけで動いているのではなく、その背後にある事業上の判断の上に成り立っている。コードだけを書いていたら、決して気づけなかった視点でした。
それでも、道が断たれたわけではありませんでした。yiyixuxu さんは、こう続けてくれたのです。
"If you make this tool as separate repo, we are happy to add it to our doc and help promote it!"
(これを独立したリポジトリにしてくれたら、私たちのドキュメントに載せて、宣伝も喜んで手伝うよ!)
コアが無理なら、コミュニティの実装として届ければいい。私は最初に出した #9986 を練り直し、今度はそれがマージされ、役目を終えたコア向けの #10006 のほうはクローズしました。遠回りはしましたが、機能はちゃんとユーザーのもとへ届いたのです。
なんでもコアに詰め込むのではなく、役割を分け、エコシステムとして共存させながら育てていく。世界中が依存する巨大なライブラリの「線の引き方」を、海外のエンジニアと英語で議論しながら肌で学べたこの経験は、今でも私の財産です。
公式リポジトリへの採用、そして v0.33.0「Significant Community Contributions」へ
メンテナからの提案を受けて、私は auto_diffusers を「外部ライブラリ」として本格的に磨き上げました。そして、そのコードが本家 Diffusers の公式リポジトリにも採り入れられました。examples/model_search というディレクトリに実装が置かれ、その README には 「auto_diffusers ライブラリが、Civitai や Hugging Face Hub でのモデル検索といった追加機能を Diffusers に提供する」 と、私のライブラリの名前がはっきりと記されました。外部ライブラリ本体だけでなく、いわばその「ミラー」となるコードが、世界中が参照する本番リポジトリの一部になった瞬間でした。
ライブラリ自体も、メンテナが示してくれた道筋どおり、私が出した PR #10358 を通じて、Hugging Face 公式の「Community Projects」ドキュメントに掲載されました。そして機能をさらに拡張した PR #10417「Enhanced Model Search」が、Diffusers のバージョン 0.33.0 のリリースにあたって、"Significant Community Contributions"(注目すべきコミュニティ貢献) として取り上げられることになったのです。
正式リリースノートに、私のハンドルネームが残った
2025 年 4 月 9 日に公開された Diffusers v0.33.0。その正式なリリースノートの "Significant community contributions" の欄に、`@suzukimain` という私のハンドルネームが、PR 番号とともにはっきりと記録されました。
Hugging Face は、米国・ニューヨークに本社を置くグローバル企業です。その製品の、世界中の開発者が読む公式リリースノート。そこに、日本に住む、しかも始めた当時は高校生だった私の名前が、確かに刻まれている。これは紛れもなく、米国発のグローバルOSSプロジェクトからの「公式の認定」でした。
匿名の誰かが書いた便利ツール、ではなく、名前のある一人の貢献者として記録に残る。OSSの世界では、コードと同じくらい「誰が貢献したか」が大切にされます。その文化の中で、自分の名前が公式に残ったことは、何よりの励みになりました。
73,000 ダウンロードという、静かな手応え
auto_diffusers の累計ダウンロード数は、73,000 を超えました。
派手な宣伝をしたわけではありません。それでも、数字は静かに積み上がり続けています。最初は自分ひとりの「面倒くさい」を消すために書いたコードが、今では世界中の、顔も名前も知らない誰かの作業を、少しだけ楽にしている。そう思うと、不思議な気持ちになります。一行のコードが、自分の部屋を飛び出して、世界のどこかで動いている。そのことが、何よりのモチベーションです。
現在、そしてこれから
いま、私は大学生になりました。正直に書くと、auto_diffusers は以前のように手厚くは管理できていません。
大学に入ってからは、関わることが一気に増えました。東京大学の方々との起業、量子リザバーコンピューティング、別プロダクトの開発、そしてイラストのセマンティックセグメンテーション。2025 年には、このセグメンテーションを題材に、Google Developer Group 主催の DevFest Tokyo 2025 で登壇する機会もいただきました。高校時代、自室で return のインデントひとつのズレに半日悩んでいた頃の自分からは、想像もできなかった景色です。正直なところ、こうした活動に追われて、Diffusers への貢献は今は少し小休止しているのが実情です。
なかでも、いま特に夢中になっているイラストのセマンティックセグメンテーションについては、いつか機会があれば、改めて記事として残したいと考えています。
高校生のとき、自室で「なければ、つくってしまおう」と踏み出した一歩が、海外の著名プロジェクトの公式認定にまでつながるとは、当時は思ってもいませんでした。いずれにせよ、あの頃に思い描いていた以上の経験を、いま積み重ねられていると感じています。
それでも、やってきたこと自体はずっと変わっていません。自分が不便だと感じたものを自分で作って解決し、同じように困っている人が使えるようにする。その繰り返しです。
いま関わっていることも、根っこは同じです。これからも、目の前の「面倒くさい」を見つけては、手を動かして片づけていくつもりです。