ニートの言葉

元ニートがやってみたこと・その過程で学んだこと・考えたこと・技術メモあたりを主に書いています。情報革命が起きた後に訪れるであろう「一億総ニート時代」の生き方を考え中です。

【日記】MacStudioに繋ぐためのHanyeのSSDを買った

LLMをローカルでも試したいと思い、1年前くらいにM3UltraのMacStudioを買った

当時はめちゃくちゃ高いと思ってたけど、半導体不足?の今となってはメモリが128GBより大きな512GBのMacはそもそも購入できなくなっているようなので買ってよかった

ちなみに、これと同じMacStudioがメルカリで300万くらいで売れていた

 

このMacStudioは4TBの容量があるけど、LLMのモデルは大きいものだと数百ギガあったり、小さいものでも数十ギガあるので、いろいろ試すと意外とすぐに容量不足になる。

そこで外付けのSSDで容量を増やしたいが速度はある程度欲しいと考えて、今回増設をしてみた。

Thunderbolt 5に対応してれば高速に使えるらしい。

購入したのはこちら

4TB で高速なものを探していたら、ほとんどが10万円を超える中、これだけ7.5万くらいだった(この記事を書いてる時には8.3万になってた。日々の変動が激しい)

素人なのでHanyeというメーカーを知らなかったし、レビューも少なく不安ではあったが、人柱になるつもりで買ってみた

ケースはこちら

SSDだけだと使えないのでエンクロージャ(ケース)が必要らしい

80Gbpsに対応したものでよく冷えそうなものとしてこれを選んだ(購入時の価格は25999円)

2つ合わせて10万円くらい。

届いた

シリコンケース?カバー?に包まれた状態で入ってました。

左にあるのはシリコンの熱伝導シートらしい

裏は銅なのかよく冷えそうな素材

SSDをつけて

シリコンの熱伝導シートを貼ったら完成


速度を計測してみた

読み込みは問題ないけど…書き込み遅くない?

家族アルバム「みてね」で一括ダウンロードする方法

こんにちは、あんどう(@t_andou)です。

子どもの写真を親族間で共有するために「みてね」を使っている人は多いと思います。
しかし、「みてね」では一括ダウンロード機能は提供していません。

参考:写真や動画の一括保存・削除はできますか?

そこで、今回は一度実行するだけで全ての写真・動画をダウンロードするプログラムを作りましたので公開します。(正確には一括ダウンロードではありませんが、一度実行すれば放置するだけで全てダウンロードしてくれます。)

自分用のメモ程度の情報なので、プログラムの実行方法などについては本記事では触れません。

やり方

1.こちらの記事を参考にブラウザからアクセスできるようにURLを発行します。

「みてね」ブラウザ版でパソコンから写真や動画をダウンロードする方法 | あいこうらのさくっとふぉとらいふ

2.pythonの実行環境準備やライブラリのインストールなど、必要な環境構築を行なってください。

3.下のソースの写真アルバム部分を1で発行したURLに変更して実行。

 

gist.github.com

【ChatGPTとStableDiffusion】絵本を描くAIをつくる その1

どうもこんにちは、あんどう(@t_andou)です。

最近は子供の寝かしつけで毎晩絵本を3~5冊読んであげているのですが、同じ本を手に取りがちなのでもう少しいろんな種類の絵本を読んであげたいと考えました。

新しく買っても良いのですが、すでに絵本の棚が溢れかけているのであまり増やしたくなく、一方で毎回図書館に借りに行くのも面倒。

そこで、絵本を描いてくれるAIを作りたいと思います。

大まかな流れ

第1回:今回

品質は問わず、ChatGPTで作った物語にイラストを付けてみるテスト

第2回

作成した絵本をweb上で絵本を見れるようにする

第3回

イラストのクオリティを上げる

第4回

物語のクオリティを上げる

第5回

webサービスのブラッシュアップ:作成リクエストを出せる・読み上げ機能など

まずは結果から

物語と画像生成用promptはChatGPT-3.5による生成
画像生成はStableDiffusion1.5を使っています

一つ目:ちいさなロボットの冒険

SF、8ページ、3歳児向け と指定

ちいさなロボットの冒険

 

二つ目:マックスとバスターの冒険

動物との友情、12ページ、5歳児向け と指定

 

マックスとバスターの冒険

三つ目:ホッピーの冒険

風船で空を飛びたいウサギの話、8ページ、3歳児向け と指定

ホッピーの冒険

感想と今後について

起承転結も書けていて、最初のチャレンジにしては大成功な印象です。12ページでも一回で生成できるのはすごいですね。

しかし、所々不自然な日本語があったり、タイトルが全部「〜の冒険」だったりするので、物語の生成も工夫の余地が大いにありそうです。

今回は一発で全ページ分を書かせましたが
1.事前に起承転結に分けてプロットを書かせる
2.事前に登場人物の設定をしっかり考えさせる
3.前のページまでの話を要約して入力する
などで品質が上がったりしないかなと思ってます。

あと、低年齢の場合は全てひらがなで書くような指定もしたいところです。

イラストの品質についてはまだ何も分からないのでこれから調べます。

技術メモ

最後に、自分用の技術メモを兼ねて下に残しておきます。

1.物語を作る

ここはChatGPTに任せます。

ターゲットの年齢やカテゴリ、ページ数を指定することで、タイトル・概要・各ページごとの挿入するテキストとイラスト生成のための文章をjson形式で生成させます。

promptの例はこんな感じです。

Please generate a 8 pages picture book which category is SF for 3 years old. For each page, provide the text to be included in the book and a description of the illustration to accompany it.Output must be following json format\n{\n    "title": "title",\n    "title_jp": "title_jp"\n    "coverIllust": "description for cover illust",\n    "summary": "summary",\n    "content": [\n        {"page": 1, "text": "text in picture book","text_jp":"Japanese of text", "illustration_description": "description for illust"},\n        {"page": 2, ...}\n    ]\n}

この結果が以下になります。

{'title': "The Little Robot's Adventure",
 'title_jp': 'ちいさなロボットの冒険',
 'coverIllust': 'The cover illustration shows a small, friendly-looking robot standing in a field of colorful, blooming flowers. The setting sun paints the sky in hues of orange and purple, creating a warm and inviting atmosphere.',
 'summary': 'Join the Little Robot on an exciting journey through space and discover the wonders of the universe!',
 'content': [{'page': 1,
   'text': 'Once upon a time, in a land far away,\nA little robot named Andy loved to play.\nHe dreamed of exploring far beyond Earth,\nTo see the stars and planets of infinite worth.',
   'text_jp': 'むかしむかし、遠い国で、\nアンディという小さなロボットが遊ぶのが大好きでした。\n彼は地球の遠くを探検し、\n無限の価値を持つ星と惑星を見たいと夢見ていました。',
   'illustration_description': 'Andy, the little robot, can be seen in his cozy workshop, surrounded by gears, wires, and tools. His eyes are gleaming with excitement as he looks at a poster of outer space.'},
  {'page': 2,
   'text': "One night, a shiny meteor fell from the sky,\nAnd landed right before Andy's eyes.\nIt was a spaceship, oh, what a sight!\nAndy's heart raced with pure delight.",
   'text_jp': 'ある夜、輝く流星が空から落ちてきて、\nアンディの目の前に着地しました。\nそれは宇宙船で、何て素晴らしい光景でしょう!\nアンディの心は純粋な喜びで躍りました。',
   'illustration_description': "Illustration shows the spaceship, shimmering with metallic colors and emitting a soft glow, in front of Andy's workshop. Andy stands in awe, his eyes widened with excitement."},
  {'page': 3,
   'text': 'He hopped inside, with a bleep and a bop,\nAnd pressed a button to start the top.\nThe spaceship zoomed up into the sky,\nAs Andy waved Earth a heartfelt goodbye.',
   'text_jp': '彼はビープとボップとともに中に入り、\nボタンを押してスタートさせました。\n宇宙船は空に飛び上がりました。\nアンディは地球に心からさよならを告げました。',
   'illustration_description': "Andy is seen inside the spaceship, sitting in the pilot's seat with a control panel full of buttons and switches. The ship is blasting off into the night sky, leaving behind a tail of stardust."},
  {'page': 4,
   'text': 'Through galaxies far and nebulas bright,\nAndy traveled each day and every night.\nHe saw shooting stars and planets of blue,\nAnd discovered wonders he never knew.',
   'text_jp': 'アンディは遥かな銀河と明るい星雲を通って、\n昼も夜も旅をしました。\n彼は流れ星や青い惑星を見ましたし、\n知らなかった驚きを見つけました。',
   'illustration_description': "Andy's spaceship is shown soaring through space, passing by colorful nebulae and sparkling stars. Andy's face reflects amazement and curiosity as he gazes out the window."},
  {'page': 5,
   'text': "But soon, Andy missed his dear home,\nWhere friendly faces used to roam.\nHe decided it was time to return,\nWith memories and knowledge he'd earned.",
   'text_jp': 'しかし、アンディはすぐに大切な故郷を恋しく思いました。\n昔は友達の顔がいっぱいでした。\nアンディは帰る時がきたと決め、\n思い出と知識を持ち帰ることにしました。',
   'illustration_description': 'The illustration depicts Andy sitting in his spaceship, a hint of nostalgia in his eyes as he looks back at Earth. The backdrop showcases distant planets and stars, symbolizing the vastness of space.'},
  {'page': 6,
   'text': "With a flick of a switch, he sailed back,\nEntering Earth's atmosphere, no time to slack.\nThe spaceship landed softly on familiar ground,\nReuniting him with friends all around.",
   'text_jp': 'スイッチをポチっと押すと、彼は引き返しました。\n地球の大気圏に入る瞬間、時を惜しまず。\n宇宙船は馴染み深い地面にやさしく着陸し、\n彼は周りの友達と再会しました。',
   'illustration_description': 'The spaceship gently descends, surrounded by a crowd of joyful friends eagerly waiting to welcome Andy back. The scene is filled with laughter, hugs, and the warmth of friendship.'},
  {'page': 7,
   'text': 'Andy shared stories of his great exploration,\nOf planets and stars in a fantastic formation.\nHis friends listened with awe and delight,\nDreaming of their own adventures each night.',
   'text_jp': 'アンディは偉大な探検の話を友達と共有しました。\n幻想的な形成物の惑星と星の話を。\n友達は畏敬と喜びをもって聞き、\n毎晩自分自身の冒険を夢見ました。',
   'illustration_description': 'In this illustration, Andy is seen surrounded by his friends, their eyes wide with wonder as he recounts his thrilling adventures in space.'},
  {'page': 8,
   'text': "From that day on, the little robot's quest\nWas to inspire others to be their best.\nTo look at the stars with wide-eyed glee,\nAnd believe that anything's possible, you see!",
   'text_jp': 'その日から、その小さなロボットの目的は\n他の人々に最善を尽くすことを奮起させることでした。\n笑顔で星を見ることを通じて、ワクワクして、\nどんなことでも可能だと信じることなんですよ!',
   'illustration_description': 'The final illustration showcases Andy surrounded by a group of children, all gazing up at the night sky in wonder and awe. Their faces radiate excitement and hope for the future.'}]}

日本語のタイトルやテキストは別処理で翻訳しても良いのですが、今回は第1回ということで、サクッと成果物を見たかったため一緒に書いてもらいました。

2.1で生成したイラストの説明文でイラストを生成

1で生成した説明文を使って画像を生成します。

ここでは手元のGPUマシンでStableDiffusionを起動して、そこにAPIでリクエストを投げています。

APIサーバーの記号は次のコマンドで、生成リクエストは後述

python launch.py --server-name 0.0.0.0 --xformers --xformers-flash-attention --nowebui --listen

3.イラストに物語を入れる

ChatGPTが生成したjsonの情報を使って、全ページ分の画像を生成し、最後に画像と文章を合成します。

# Stable Diffusion Web UIのURLを設定します
url = "http://192.168.1.100:7861/sdapi/v1/txt2img"
import os
import json
import requests
import base64
from PIL import Image, ImageDraw, ImageFont
import textwrap
from io import BytesIO

font_path = "Nちはやフォント+.ttf"

def generate_and_save_image(prompt, path):
    payload = {"prompt": "Illustration:"+prompt} # ここでSDのパラメータを指定する
    response = requests.post(url, json=payload)
    image_data = base64.b64decode(response.json()['images'][0])
    image = Image.open(BytesIO(image_data))
    image.save(path)

def add_text_to_image(image_path, text, font_path, canvas_size=(512*2, 512)):
    canvas = Image.new('RGBA', canvas_size, (255, 255, 255, 255))
    image = Image.open(image_path)
    canvas.paste(image, (0, 0))

    draw = ImageDraw.Draw(canvas)
    font = ImageFont.truetype(font_path, 30)
    lines = textwrap.wrap(text, width=15)
    y_text = canvas_size[1] // 2 - len(lines) * 15

    for line in lines:
        bbox = draw.textbbox((0, 0), line, font=font)
        width = bbox[2] - bbox[0]
        draw.text(((canvas_size[0]/2 - width) / 2 + canvas_size[0]/2, y_text), line, font=font, fill="black")
        y_text += 30

    canvas.save(image_path)

# タイトルに基づいてディレクトリを作成します
os.makedirs(book_data["title"], exist_ok=True)
os.makedirs(os.path.join(book_data["title"],book_data["title_jp"]),exist_ok=True)

# book_dataをJSON形式で保存します
with open(os.path.join(book_data["title"], "text.json"), 'w') as f:
    json.dump(book_data, f)

# カバー画像を生成します
cover_image_path = os.path.join(book_data["title"],book_data["title_jp"], "0.png")
generate_and_save_image(book_data["coverIllust"], cover_image_path)

# カバー画像にテキストを追加します
add_text_to_image(cover_image_path, book_data["title_jp"], font_path)

# 各ページの画像を生成します
for page_data in book_data["content"]:
    page_image_path = os.path.join(book_data["title"],book_data["title_jp"], f"{page_data['page']}.png")
    generate_and_save_image(page_data["illustration_description"], page_image_path)
    add_text_to_image(page_image_path, page_data["text_jp"], font_path)

ChatGPTでコピペできるテンプレートを選べるサイトを作った【完全無料】

どうもこんにちは、あんどう(@t_andou)です。

ChatGPTと会話をする際に「英会話の教師として相談に乗ってほしい」とか「小説を校正してほしい」とか「ブッダになってほしい」などなど…ありますよね。

そんな時には次のプロンプト集が便利です。

便利なプロンプト集

https://github.com/f/awesome-chatgpt-prompts

こちらに役割とpromptのセットが大量にあり便利なのですが、英語なのでぱっと見わかりづらいため日本語でさっとコピペできるサイトを作りました。

作ったサイト

https://chatgpt-templates.web.app/

使い方

  1. 日本語で会話したい場合は「日本語で回答させる」にチェックを入れる
  2. ChatGPTに期待する役割を選択する
  3. 出てきたテンプレートをコピー
  4. ChatGPTにペーストして使う

具体例

webデザインコンサルタント

酔っ払い

最後に

完全無料なのでぜひ使ってみてください。

また、ChatGPTなどでこんなことは出来ないか?などのご相談もお待ちしてます。(簡単にできるものであればブログなどで公開することを条件に無料で作るかもです)

ChatGPTの実験 : DBを作る

どうもこんにちは、あんどう(@t_andou)です。 今回はChatGPTのAPIを使って遊んでみたのでメモをしておきます。

背景

ChatGPTに生成させる際にフォーマットを指定する事で構造化データ(CSVやDBなど特定のフォーマットに則ったデータ)が作れそうだと考えました。

ChatGPTは2021年までの情報しか学習させていない上に正確性に欠けるため、ダミーデータを作ることなどが適切な使用法だとは思うものの、移り変わりの少なそうな観光地情報などであればある程度実用に耐えられるかも?そこも実験してみようと判断し、全国の観光情報DBを作ってみることにしました。

やったこと

  • ChatGPT APIを使って全都道府県のアクティビティ・観光情報(18493件)を集め(生成し)DBを作った
  • 表示するwebアプリを作った

作ったもの

URL

https://tabi-ai.web.app/

使い方

都道府県を選択するとおすすめのアクティビティや観光地がランダムに最大9件くらい表示されます。
各アクティビティには名称、詳細、所要時間やコスト、難易度、対象年齢などの情報を載せてます。

今後の予定

モチベーション次第ですが、予算や滞在時間を選択するとおすすめのプラン(移動時間や営業時間は無視)を組み立てるところまで出来そうだしやりたい

やってみてわかったこと

  • 決まったフォーマットでと指定しているにも関わらず、ChatGPTがたまに我に返って変な前置きをしたりするので、そういう時はエラーが出るが素直にやり直すのが吉(例外処理を詳細に書くよりコストが安いと判断)
  • ChatGPTはDB作成にも使えた
  • 全都道府県18493件のデータを集めたが、かかったコストは12ドルくらい
  • アクセスを分散すればもっと早く終わると思うが1日くらいかかった

当然だけどDBにする事で下記も見込める - レスポンス速度の向上 - レスポンス長の制限無し - 1呼び出しあたりのコストが激安になる

まとめ

正確性は未検証なものの、飲食店のおすすめよりもちゃんとしたデータが出てきてそう。 この規模のデータベースを1日でしかも12ドルで作れるのはなかなか良い感じ。

プロフィールなどのデータ作成は向いているので、↓こういうこともやりたい。

もっと詳しい作り方を知りたいという方は僕と友達になってください。

あんどう@AI開発者 (@t_andou) / Twitter

それでは。

高精度な文字起こしAIで古い映画の字幕を作ってみたら酷かった

 

どうもこんにちは、あんどう(@t_andou)です。

前回、高精度なAIを使って動画の字幕を作る方法を書きました。

前回の記事

blog.takuya-andou.com

今回やったこと

講演などの動画ではだいぶ良い精度が出ていたため、字幕がついていないパブリックドメインの古い映画に対しても自動的に良い感じの字幕が付けられたら良いなと思い試してみました

結果として、全然ダメでした。

供養のために記事に残しておきます。

字幕無しの方が映画をお楽しみいただけるかと思います。

youtu.be

 

こちらはついでにカラー化しました。

youtu.be

 

それではまた。

文字起こしAIで誰でも無料でYoutubeの字幕ファイルを作る方法

どうもこんにちは、あんどう(@t_andou)です。

前回宣言した通りに誰でも簡単にYoutubeの字幕ファイルを作る方法を書きます。
「Youtubeの」と書いていますが、実際はどの動画でも対応してます。

前回の記事

blog.takuya-andou.com

まずはGoogleColabの共有

colab.research.google.com

 

使い方

GoogleColabに記載していますが

1.GPUを使用するように切り替え

上の「ランタイム」→「ランタイムのタイプを変更」からからGPUを選択

2.右上の接続

下のセルを実行すると自動的に接続されるので省略可能です

3.動画をアップロード

ここにドラッグ&ドロップでアップできます

大容量のデータの場合、GoogleDriveと連携した方が効率的です

4.入出力のパスの変更

ファイル名に合わせて変更してください

5.全セルを実行

あとは待つだけで完了です。

注意

whisperの不具合なのか、たまに終了の時刻が開始の時刻よりも先になっていたり、時間がおかしいことがあります。
Youtubeにインポートする際にどの行にエラーがあるかが表示されるので手作業で修正してください。

気分が乗ったら修正する処理を追加するかもしれません。