2025年10月1日水曜日

ボットは絵も動画もブログも作成できるようになった

ボットは絵も動画もブログも作成できるようになった

人生とはボットを育てることなのかもしれない

これまで

https://blog.kakakikikeke.com/2025/04/kakakikikeke-die-twice.html

自分のツイートを学習させて自分っぽいツイートができるようになりました

アカウント

https://x.com/kakakikikekebot

現在のボットにできること

2025/09/26 現在ボットは成長し以下ができるようになりました

  • ツイートをする
  • ブログを書く
  • 絵を書く
  • ショート動画を作る

以下それぞれの仕組みを詳細に説明します

共通点

  • 動作マシンはローカルの M2 Pro mac mini
  • バックエンドでは「CPU50%のマイニング」「Ollamaサーバの起動」「SD-webui」が稼働している
  • 生成時は MPS にすべて対応しているものを採用
  • Python で実装
  • 生成時間は動画以外数分で完了 (絵、文章系)

ツイートをする

Twitter API + Ollama API (gemma3)

  • 自分のツイートを500件準備、そこから20件をプロンプトのコンテキストとして与える
  • ツイートを生成してもらうようなプロンプトを入力
  • レスポンスをパース、サニタイズなど調整してからツイート
  • ハッシュタグやリンクなどは含めないようにしている
  • プロンプトは以下
def build_prompt(past_tweets, sample_size=20):
    examples = "\n".join(random.sample(past_tweets, sample_size))
    return f"""以下は過去のツイートです:

----ここから過去のツイート----
{examples}
----ここまで過去のツイート----

これらの文体や話題を参考にして、あなたらしい新しいツイートを1つ生成してください。
日本語でかつ文章の意味がわかるような自然なツイートにしてください。
ツイートに「https://」から始まるようなURLは絶対に含めないでください。
ツイートの長さは50文字以内にしてください。
ツイートを作成した理由などは説明しないください、ツイートのみ生成してください。
"""

ブログを書く

Twitter API + Blogger API + Ollama (gemma3)

  • テーマを与えてそのテーマに基づいたブログ記事を書いてもらう
  • 出力は必ずHTMLになるようにプロンプトで調整、デフォルトがMarkdownっぽいので可能な限りMarkdownにならないようにする
  • テーマはランダムで100件保持、100件分のテーマを消費すると停止する
  • テーマはChatGPTに生成してもらっている
  • プロンプトは以下
def build_prompt_for_blog_post(theme):
    return f"""以下はブログ記事のテーマです。

----ここからテーマ----
{theme}
----ここまでテーマ----

このテーマを参考にして、あなたらしい新しいブログ記事を1つ生成してください。
ブログ記事内では Markdown 記法は使えません、Markdown 記法は自動で HTML に変換されません。絶対に Markdown 記法を使わないでください。
ブログ記事は Markdown 記法を使わずに生成してください。
ブログ記事内では HTML タグが使えます。
コードなどシンタックスハイライトが必要な場合は HTML タグを使ってください。
ブログ記事に画像は含めないでください。
ブログ記事内に StyleSheet や CSS の記述を含めることは可能ですがブログ本体の StyleSheet や CSS に影響を与えないようにしてください。
ブログ記事を作成した理由などは説明しないください、ブログ記事の内容のみ生成してください。
"""

絵を書く

Twitter API + Stable Diffusion WebUI API (model はランダム)

  • SD-Web UI を API モードで起動してそれをコールする
  • SD-Web UI の命令はそのまま JSON のペイロードとして API に送信できるので楽
  • 生成された画像のサイズは896x1152
  • モデルは固定ではなく10個ほど保持しておりそれを順番に使用していくように Python 側で制御
  • プロンプトもランダムになるようにしておりベース、性別、向き、服装、背景など要素ごとに毎回ランダムで生成するようにしている
def generate_prompt():
    # プロンプトの定義
    base = "masterpiece, best quality, ultra-detailed, 8k, cinematic lighting"
    gender = "".join(
        ("1 beautiful japanese young women, fair skin, light makeup, realistic face")
    )
    viewpoint = get_random_viewpoint()
    posing = get_random_posing()
    hair_cut = get_random_hair_cut()
    hair_color = get_random_hair_color()
    hair = f"{hair_color} {hair_cut}"
    face = get_random_face()
    background = get_random_backend()
    tops = get_random_tops()
    bottoms = get_random_bottoms()
    clothes = f"{tops}, {bottoms}"
    return "".join(
        f"{base}, {gender}, {viewpoint}, {posing}, {hair}, {face}, {background}, {clothes}",
    )

ショート動画を作る

Twitter API + Stable Diffusion WebUI API + LTX-Video (txv-2b-0.9.8-distilled)

  • text-to-video ではなく image-to-video の手法
  • 先に SD-WebUI を使って画像を作成してもらう
  • その画像を使って LTX-Video で動画にする
  • 256x384の4秒動画を作成 (num_frames=121、frame_rate=30)
  • 4秒以上の動画を生成する場合は192x256にすれば生成できる
  • 本当は896x1152で生成したいがリソースが足りない
  • 動画の生成はほぼマシンリソースをすべて使うので生成前にマイニングおよび ollama の runner を停止している
  • 各種プロセスを停止しないとメモリが枯渇してほぼ100%クラッシュする
  • 1動画生成するのに20-60分ほどかかる
  • 生成時間にムラがありおそらく入力している画像の影響だと思われるが安定しない
  • LTX-Video をサブプロセスとしてコールしているのでその作りが微妙
def convert_image_to_video(
    img_filename: str, width: int, height: int, prompt: str = ""
) -> Optional[str]:
    # 環境変数からパスを取得、設定がなければデフォルト値を使用
    work_dir = os.getenv("LTX_WORK_DIR", "/Users/kakakikikeke/Documents/work/LTX-Video")
    img_dir = os.getenv("LTX_IMG_DIR", "/Users/kakakikikeke/data/repo/videobot")

    # 仮想環境の Python を直接指定
    venv_python = os.path.join(work_dir, "env", "bin", "python")

    # 実行コマンド
    command = f"""
    cd {work_dir} && \
    PYTORCH_MPS_HIGH_WATERMARK_RATIO=0.0 \
    {venv_python} inference.py \
    --prompt "{prompt}" \
    --conditioning_media_paths {img_dir}/{img_filename} \
    --conditioning_start_frames 0 \
    --height {height} \
    --width {width} \
    --pipeline_config configs/ltxv-2b-0.9.8-distilled.yaml
    """

今後追加したい機能

  • 音楽の作成
    • AudioGen
    • RVC
  • 長めの動画
    • 今のマシンだと画像サイズを落としてフレーム数を上げるしかない
    • もっと軽量なモデルを探す
    • 本当はWan2.2やVeo3レベルの動画を生成したい
  • 俳句
    • gemma3 でプロントプト換えるだけ
  • 音楽+動画
    • 上記で生成した音楽と動画を何かしらで組み合わせる
    • 最終形はこれなのかもしれない
  • 昔の写真や自分で書いた絵を動画にしたい
    • 過去の復元
    • 手書きの絵 -> アニメ化 -> 動画化
  • NanoBanana 連携
    • 有料だとかなり強力
    • というかお金を使う前提ならローカルで全部動かさないで Google AI Studo API や Colab でガンガン動かして高品質、高画質、長尺コンテンツを作りまくれる
    • ただマネタイズ考えないと大変なことなりそう
    • 動画にするだけならVeo3でもいける

課題

  • Twitter API Free プランの上限
    • 500ツイート/1日にほぼ当たっている
    • 有料プランにすれば解決するがどうするか
    • コンテキスト(メディア系、テキスト系)にアカウントを分割するか、管理は面倒になる
  • Ollama で動作させるモデル
    • gemma3 はだいぶ軽量なので動作する
    • gpt-oss のような大規模LLMは動作しない (動作はするがスワップだらけでかなり遅くなる)
    • openhermes など試したがハッシュタグや無駄に絵文字を使うのでやめたりした
    • いいモデルを探すのが難しい
  • プロンプトだけで制御するのには限界がある
    • 含めないでと命令しても含めてくる
    • モデルに合ったプロンプトを調整しなければいけないのが辛いのでなんとかしたい (プロンプト最適化など)
  • プロンプトのパターン追加
    • テーマなど手動の部分があるので自動化したい
    • 絵を描く際のプロンプトのランダム抽出の候補を追加する
    • そもそも完全ランダムにする方法を考える
  • 絶望的にマシンスペックが足りない
    • やはり AppleSilliocn だとかなり辛い
    • 基本は RTX などの CUDA が使えるグラボがあることが前提 (xformers動作など)
    • 動画生成は特に VRAM を消費するので VRAM モリモリのグラボがないと厳しい (Wan2.2など)
  • ディスクも足りない
    • ローカルにモデルを置きまくっているのでディスクが枯渇する

最後に

多少の知識はいるが生成系は本当に楽な時代になった