2024年6月26日水曜日

mlx-examples の LoRA を使って kakakikikeke っぽいツイートを自動生成してみた

mlx-examples の LoRA を使って kakakikikeke っぽいツイートを自動生成してみた

画像生成は stable-diffusion を使いました
音声生成は RVC を使いました
今回は文章生成をします

環境

  • macOS 14.5
  • Python 3.10.12
  • mlx-examples 69700d84

学習データの作成

Twitter のアーカイブデータを使います
アーカイブデータ内に tweets.js というツイートを管理しているファイルがあるのでそこから学習データとテストデータと評価データを作成します

学習させるツイートの元では 3 万件ほどありますが全部は学習させません
本当は全部学習させたいのですがマシンのスペックも考慮して 1300 件にしています
テストと評価データはそれぞれ 100 件ずつです

wc -l my_tweet/*
     100 my_tweet/test.jsonl
    1100 my_tweet/train.jsonl
     100 my_tweet/valid.jsonl
    1300 total

このデータセットの量でだいたい 1 時間ほどで LoRA を生成できるので 3 万件学習させても 4 日ほどあれば終わるかもしれません

学習データ作成スクリプト

以下 tweets.js を解析して学習データを作成するための Python スクリプトです
pandas と scikit-learn が必要になります
json ファイルを解析するだけなので pandas も scikit-learn もなしで解析することもできます

import json
from io import StringIO

import pandas as pd
from sklearn.model_selection import train_test_split

# tweets.js を読み込んでツイート情報を辞書に変換
tweets = []
with open("./tweets.js", mode="r") as f:
    for tweet in json.loads(f.read().replace("window.YTD.tweets.part0 = ", "")):
        t = {
            "full_text": tweet["tweet"]["full_text"],
            "created_at": tweet["tweet"]["created_at"],
        }
        tweets.append(t)

# JSONデータをPandas DataFrameに読み込む
df = pd.read_json(StringIO(json.dumps(tweets)))
pd.set_option("display.max_colwidth", 1000)
pd.set_option("display.max_rows", 1000)

# リンクを含むツイートは削除
df = df[~df["full_text"].str.contains("https://")]

print(df.head(100))

# テキスト長が短い学習データTOP1300をデータセットとして扱う
# 学習に時間がかかる場合もしくはメモリを使いすぎる場合は ascending=True にして短い順にするか 1300 の数を小さくすること
df["length"] = df.full_text.str.len()
df = df.sort_values(by="length", ascending=False)
df = df.head(1300)
print(len(df.index))

# データフレームをシャッフル
df = df.sample(frac=1).reset_index(drop=True)

# validとtest用のデータを100件ずつ取り出し、残りをtrainに分割
valid_df, remaining_df = train_test_split(df, test_size=len(df) - 100, random_state=42)
test_df, train_df = train_test_split(
    remaining_df, test_size=len(remaining_df) - 100, random_state=42
)


# ヘルパー関数:データフレームを新しい形式でJSON Linesファイルに変換
def df_to_jsonl(df, file_name):
    with open(file_name, "w", encoding="utf-8") as file:
        for _, row in df.iterrows():
            formatted_data = {"text": f"USER:ツイートして ASSISTANT:{row['full_text']}"}
            file.write(json.dumps(formatted_data, ensure_ascii=False) + "\n")


# 各データセットを対応するJSON Linesファイルに変換
df_to_jsonl(train_df, "./train.jsonl")
df_to_jsonl(valid_df, "./valid.jsonl")
df_to_jsonl(test_df, "./test.jsonl")

最終的には3つのファイルが作成できればいいので解析方法はおまかせします

ベースモデル

学習させるデータが日本語なのでベースモデルも日本語に特化したものを使ったほうがいいです
今回は https://huggingface.co/4bit/ELYZA-japanese-Llama-2-7b-instruct を使いました
また mlx は専用のフォーマットにモデルをコンバートする必要があるのでモデルをダウンロードしたら mlx-examples に含まれる convert.py を使って変換します

  • cd mlx-examples/lora
  • python convert.py --hf-path 4bit/ELYZA-japanese-Llama-2-7b-instruct -q --q-bits 4

コンバートしたモデルは mlx_model 配下に生成されます

学習

生成した学習データと変換した ELYZA のベースモデルを使って LoRA アダプタを生成します

  • python lora.py --model mlx_model --data my_tweet --train --iters 600

反復数も学習時間に影響するためあまり大きくすると学習時間が増えるので注意してください
600 回と 1300 件の学習データで約 1 時間で終了しました

推論

あとはテストします

  • python lora.py --model mlx_model --adapter-file adapters.npz --prompt "USER:ツイートして ASSISTANT:"
Loading pretrained model
Total parameters 1055.199M
Trainable parameters 2.097M
Loading datasets
Generating
USER:ツイートして ASSISTANT:iot_device には iot_device って何だよ、デバイス�も実装したいというときはどうすればいんだろうか。ま�、ros bond とかと同じ�じかな、デバイスに�する
  定を管理するクラスを作るだけだよな

何度か生成してみます

Loading pretrained model
Total parameters 1055.199M
Trainable parameters 2.097M
Loading datasets
Generating
USER:ツイートして ASSISTANT:10.5 10.6 10.7 、、、、10.9 10.10 10.11 を使うために 10 にしてるのか。ios の場合は 10.12 とかだからちゃんとやってるな、という�じ
==========
Loading pretrained model
Total parameters 1055.199M
Trainable parameters 2.097M
Loading datasets
Generating
USER:ツイートして ASSISTANT:airplay の機�ってどこの�品があるんだろうか。これから発表していくためにはコンテナに入れておかないとダメなのだろうか。����も����も結果は同じという
  とを�り返していく
==========
Loading pretrained model
Total parameters 1055.199M
Trainable parameters 2.097M
Loading datasets
Generating
USER:ツイートして ASSISTANT:その google colaboratory だとあるスクリプトをコードで����すか、、、コードの�分ってやつですが、、、そのためにコードの変更�所を����のがいいんだけ
  そのためにもしくは使えるのが
==========

この文字化けは何とかならないのだろうか、、

おまけ: 文字化け対策

てっとり早く対応する場合は生成されたいろいろ弄る前のトークンを最後に print すれば OK です

git diff
diff --git a/lora/lora.py b/lora/lora.py
index a90eda7..411f558 100644
--- a/lora/lora.py
+++ b/lora/lora.py
@@ -312,6 +312,7 @@ def generate(model, prompt, tokenizer, args):
             skip = len(s) - 1
     print(tokenizer.decode(tokens)[skip:], flush=True)
     print("=" * 10)
+    print(f"{s} \n\n")
     if len(tokens) == 0:
         print("No tokens generated for this prompt")
         return

文字化け対策して10個生成してみました

結局その一緒に遊ぶやつとセットにしないとダメなんですか。通信量かかりますが gps ロガーつけている状態じゃないとダメなんですか。そういうわけだからバックグラウンドでおいておいておけばいくらか 

customerservice ルートにログインしたときに dns コマンドによってクラスタの dns サービスを停止していたため、ルートからクラスタにリクエストが行けなくなっていたようだな。対応はわかっているけど now  

docker-compose 使うときは pod とか swarm とかクラスタとか pod とか svc とか nil じゃないという感じのものを指定しないといけないんだけどなー、、、どうすればいいかなー、、、なんかいなくてないのだろうか、、、 

docker-compose の場合、ローカルの machine 名の前に 0 をつけてくればどこでもインストールできるようになったのかな、、docker の proxyswarm とかはプロキシの指定が必要とか面倒だからなー。salt の場合のマシン名でコ 

docker-compose とか YouTube とかで配布するのに役立っているのがコンテナってやつとかパブリッシュなのにコンテナが必要だとか結構あるのかな、コンテナのためのコンテナってのがあるけどどういうことなんだろう 

自前の処理って製品の説明書?移行前のデータをどこまでコピーするのかとかは援助しないかな。そういう時には「自前の処理」という概念がないから。そもそも仕様がわからんわけ 

ブログから個人サイトのための micro-flutter を作るってなると github を使ってできない理由はないだろうけど、blog を用意するとなってみんなが悩むのは同じで、その問題を解決するためにサービスがいくつ 

windows 折りたたみ式のマウスって結局何がいいんだろうか。マウスとして普通の押し出し式のもがいいから私が把持って操作したい、そして折りたたんで持ち歩きたいっていうのが気持ちだった 

確かに android 12 が 2020 年 9 月というのはかなり早い感じ。アップグレードのスケジュールはかなりの傾向があるような気がする。だけどいろいろと理由はあるんだろうか。最終的には google 

iPhone の時のプライスタグが貼り付けできないのか、実は AppStore のプライスタグが使えないのか。 tinder は使っているのにおかしい、とか思う人は apple の審査厨になっているから 

考察: 学習させるデータの修正

今回は「ツイートして」という質問に対して適当にサンプルしたツイートを学習させています
コンテキストも何もない状態の質問なので本当にランダムなツイートを生成してしまいます

ツイートする場合には本来ある程度のコンテキストが含まれていることがあり例えば梅雨の時期だったら雨に関するツイートをしたりだとか WWDC が Google I/O が開催される時期なので Apple や Google に関するツイートをしたりします
なので学習させるデータの質問にコンテキストを持たせることができれば特定の事柄や事象、特定の言葉を含んだツイートを生成することができます

単純に「ツイートして」という質問を学習させるのではなく「6月の雨に関するツイートをして」という感じで質問をカスタムできれば生成する際にも6月の雨に関するツイートを生成することができます
実際に生成する際の質問も「ツイートして」だけではなくテンプレートなどを使って「X月のYYYに関するツイートをして」という感じで自動で X, Y を埋めるようにすればコンテキストを持たせた文章を生成することができると思います

時期に関しては tweets.js に含まれているので簡単に学習データに含ませることができそうですが「YYY に関する」の部分はそう簡単にはいきません
例えばツイート情報を形態素解析してもっとも頻出している単語を YYY に設定することができそうですがそれだけだと正確なコンテキスト情報としては少し甘い気がします
ツイートに「Apple」や「Google」など特定の単語が含まれていれば問題ないですがそうでないツイートもたくさんあり単純のカウントではダメなケースがあります
なのでちゃんとやるのであれば例えばツイートの種類のようなものを判定する必要があるかなと思っており例えば「こんにちわ」や「ねる」「はぁー」みたいな文章ではなく短い単語のみのツイートはコンテキストなしという分類にし特定のコンテキストなり得る単語を含むツイートはコンテキストありとしてその場合は形態素解析を使ってそのツイート内に出現する特徴語を抽出してそれを「YYYに関する」の部分に設定すればそれっぽいコンテキストにはなるかなと思います

このあたりはツイートの自動タグ付けやネガポジ判定のような世界になってくるので論文を漁れば手法は死ぬほど出てくると思います

という感じで学習させるデータをもう少し工夫できれば完全ランダムなツイートしか生成しない問題を解決できるかなと思っています

最後に

まだまだ改善の余地はありそうですが自分っぽいツイートをする流れはだいたい把握できました
あとは学習データを修正したり生成時のプロンプトを変更すればもっと自然なツイートになるかなと思います

これまで画像、音声とやってきましたが文章生成が一番たいへんなイメージです
「自然な」日本語にするのがすごい難しいです

2024年6月15日土曜日

iOS 版ドラゴンクエスト7をプレイしたのでメモ

iOS 版ドラゴンクエスト7をプレイしたのでメモ

変数が表示されないバグとかどうでもいいのでとにかく急に落ちるのを何とかしてほしい

環境

  • iPhone14 (iOS )
  • iOS 版 DQ7 1,220円 (2021年に購入)

プレイ時間

  • 約100時間
  • そのうち10時間くらいはカジノの自動化で放置していた

ゲームの進行について

  • 全体的にマリベルのイオ系が強すぎる
  • 全体的にボスはせいけんづき+バイキルトが強すぎる
  • 主人公とガボはしばらくブーメランで大丈夫
  • ボスは「ぼうぎょ」x3、マリベルのルカニで二段階下げてからガンガンで大体勝てる
  • 行ったり来たりが辛い
  • 後半は正直どこに行けばいいのかわからないことが多いので素直に攻略サイトを見たほうがいい
  • とうぞくのはなでは見つからないアイテムはレミラーマをしないと発見できない、レミラーマはちいさなメダル目的
  • ダンジョンの地図がデフォルトで使えるのはいい
  • 石版交換でメタル系が出る石版を手に入いれれば序盤から楽にクリアできてしまう
  • 上級職で覚えたじゅもんや特技や上級職を辞めると忘れてしまう、おそらくリメイク版での仕様
  • 主人公もガンガンいこうぜとかできると楽だった

オルゴデミーラ討伐時点でのレベル

  • ダークパレスに行ける段階で石版をやり込んだのでレベルは60を超えていた
  • プレイ時間は50時間程度
  • 風のアミュレットを使ってそのままクリア
  • じゅくれんどは基本職が8割、上級職が2割くらい終わっている状態

神さま討伐時点でのレベル

  • この時点でのプレイ時間は100時間程度
  • じゅくれんどは基本職、上級職がカンストで特級職もほぼ終わっている状態
  • やりすぎた
  • 4精霊も同じレベルで状態でクリア
  • Lv99 スライムマジュラの地図がラスボス

ゲームの操作について

  • 画角が狭すぎる、調整できない、ゆえに周りを確認しづらい
  • 3D酔いしそう
  • ツボやタンスを調べるときに村人が近くにいると割りづらい
  • 序盤のカラーストーン採掘場の石の操作が難しすぎる
  • ちいさなメダル数や熟練度の数を確認するときに変数が展開されずに変数名が出るバグがある

レベル上げ

  • クリアするだけなら基本はやる必要なし、普通に進行していればそれなりのレベルになる
  • やるなら石版交換のメタルダンジョンでまじんぎり
  • 熟練度上げを優先しないと先に Lv99 になってしまうので経験値がもったいないことになる

熟練度

  • 自作の石版なら何でも OK

最強パーティ

  • しんぴのよろいが装備できるのでガボを抜いたパーティがよさそう

やりこみ要素

  • ちいさなメダル
  • モンスターパーク (いいモンスター石版集め
    • はやぶさのくつ (スタンプ150
    • レアアイテム (ボス敵ドロップ
  • モンスター職
  • レベル99
  • じゅくれんど

アイテム、お金稼ぎ

  • 石版でタルが大量に出るフィールド (カラーストーン採掘場の入口、どっかの塔の入口) があるのでそこでタルを割って即帰宅を繰り返す

カジノコイン稼ぎ

  • 昔作った自動タップくんを使って 100 コインスロットで一日回せば勝手に MAX までいってくれる

種稼ぎ

  • やってないがモンスターを倒すしかなさそう

モンスター石版について

  • 強いボスだとレアアイテムをドロップすることがある
  • 同じ名前の地図は一度クリアするとレアアイテムはドロップしないっぽい
    • -> あくまでも確率だから周回していれば落ちるっぽい
    • 自分が生成した石版でサタンメイルがボスの地図を何回も周回したら何回も「真しんぴのよろい」が手に入ったので運次第
  • Lv99 の人が作っている地図は基本長い
  • Lv99 の人が作っている地図でもボスが弱いことがある
  • 連れて行ったモンスターが作成された石版に出現する
  • 先頭に設定したモンスターがボスになる
  • 詳しくはこのあたりを参照

最後に

石版のせいでゲーム性が崩壊しているので石版を利用はほどほどにしましょう

2024年5月31日金曜日

kakakikikeke を AI で大量生成してみました

kakakikikeke を AI で大量生成してみました

StableDiffusion の LoRA を作成して大量の kakakikikeke を作成してみました
これで永遠に自分が生成できます

環境

  • M2 Pro mac mini (macOS 14.5
  • Stable Diffusion WebUI 1.9.4
  • sd-scripts 0.8.7

学習させる画像

自分の昔の写真(15年くらい前の写真)を使いました
画像サイズはすべて 512x512 です

できれば 20-50 枚くらい準備したほうが精度が良いのですがとりあえずお試しなので 1 枚の画像から 4 枚の異なる背景の画像を用意しました
また少しだけ傾けけたりしています
こうすることで背景を変更させたりすることができます

画像のタグ情報を生成する

画像以外に画像のメタ情報を設定することでよりプロンプトで LoRA を強調することができます
タグ設定には https://github.com/toriato/stable-diffusion-webui-wd14-tagger を使っています

一応抽出できたタグ以外に個別のタグとして「kakakikikeke」を追加しました

LoRa の作成

LoRA の生成には有名な https://github.com/kohya-ss/sd-scripts を使いました
Apple Sillicon 上で動作させるには少し特殊な設定が必要になります

以下に学習時のパラメータを乗せておくので Apple Sillicon 上で動作させたい場合には参考にしてください

xformers を使わなかったり各種 precision の値、最適化関数を AdamW にするあたりが Apple Sillicon 上で動作させるポイントかなと思います
ちなみに画像の学習回数は15回です (ディレクトリに含める値なので以下では設定できない値)

ステップ数が 400 で画像が 4 枚で学習回数が 15 回でだいたい 1 時間くらいで完了します
もっと画像を増やしたりステップを増やしてもいいかもしれません


  "LoRA_type": "Standard",
  "LyCORIS_preset": "full",
  "adaptive_noise_scale": 0,
  "additional_parameters": "",
  "async_upload": false,
  "block_alphas": "",
  "block_dims": "",
  "block_lr_zero_threshold": "",
  "bucket_no_upscale": true,
  "bucket_reso_steps": 64,
  "bypass_mode": false,
  "cache_latents": true,
  "cache_latents_to_disk": false,
  "caption_dropout_every_n_epochs": 0,
  "caption_dropout_rate": 0,
  "caption_extension": ".txt",
  "clip_skip": 1,
  "color_aug": false,
  "constrain": 0,
  "conv_alpha": 1,
  "conv_block_alphas": "",
  "conv_block_dims": "",
  "conv_dim": 1,
  "dataset_config": "",
  "debiased_estimation_loss": false,
  "decompose_both": false,
  "dim_from_weights": false,
  "dora_wd": false,
  "down_lr_weight": "",
  "dynamo_backend": "no",
  "dynamo_mode": "default",
  "dynamo_use_dynamic": false,
  "dynamo_use_fullgraph": false,
  "enable_bucket": true,
  "epoch": 1,
  "extra_accelerate_launch_args": "",
  "factor": -1,
  "flip_aug": false,
  "fp8_base": false,
  "full_bf16": false,
  "full_fp16": false,
  "gpu_ids": "",
  "gradient_accumulation_steps": 1,
  "gradient_checkpointing": false,
  "huber_c": 0.1,
  "huber_schedule": "snr",
  "huggingface_path_in_repo": "",
  "huggingface_repo_id": "",
  "huggingface_repo_type": "",
  "huggingface_repo_visibility": "",
  "huggingface_token": "",
  "ip_noise_gamma": 0,
  "ip_noise_gamma_random_strength": false,
  "keep_tokens": 0,
  "learning_rate": 0.0001,
  "log_tracker_config": "",
  "log_tracker_name": "",
  "log_with": "",
  "logging_dir": "log",
  "loss_type": "l2",
  "lr_scheduler": "cosine",
  "lr_scheduler_args": "",
  "lr_scheduler_num_cycles": 1,
  "lr_scheduler_power": 1,
  "lr_warmup": 10,
  "main_process_port": 0,
  "masked_loss": false,
  "max_bucket_reso": 2048,
  "max_data_loader_n_workers": 0,
  "max_grad_norm": 1,
  "max_resolution": "512,512",
  "max_timestep": 1000,
  "max_token_length": 75,
  "max_train_epochs": 0,
  "max_train_steps": 400,
  "mem_eff_attn": false,
  "metadata_author": "",
  "metadata_description": "",
  "metadata_license": "",
  "metadata_tags": "",
  "metadata_title": "",
  "mid_lr_weight": "",
  "min_bucket_reso": 256,
  "min_snr_gamma": 0,
  "min_timestep": 0,
  "mixed_precision": "no",
  "model_list": "custom",
  "module_dropout": 0,
  "multi_gpu": false,
  "multires_noise_discount": 0.3,
  "multires_noise_iterations": 0,
  "network_alpha": 1,
  "network_dim": 8,
  "network_dropout": 0,
  "network_weights": "",
  "noise_offset": 0,
  "noise_offset_random_strength": false,
  "noise_offset_type": "Original",
  "num_cpu_threads_per_process": 2,
  "num_machines": 1,
  "num_processes": 1,
  "optimizer": "AdamW",
  "optimizer_args": "",
  "output_dir": "model",
  "output_name": "kakakikikeke",
  "persistent_data_loader_workers": false,
  "pretrained_model_name_or_path": "runwayml/stable-diffusion-v1-5",
  "prior_loss_weight": 1,
  "random_crop": false,
  "rank_dropout": 0,
  "rank_dropout_scale": false,
  "reg_data_dir": "",
  "rescaled": false,
  "resume": "",
  "resume_from_huggingface": "",
  "sample_every_n_epochs": 0,
  "sample_every_n_steps": 0,
  "sample_prompts": "",
  "sample_sampler": "euler_a",
  "save_as_bool": false,
  "save_every_n_epochs": 1,
  "save_every_n_steps": 0,
  "save_last_n_steps": 0,
  "save_last_n_steps_state": 0,
  "save_model_as": "safetensors",
  "save_precision": "float",
  "save_state": false,
  "save_state_on_train_end": false,
  "save_state_to_huggingface": false,
  "scale_v_pred_loss_like_noise_pred": false,
  "scale_weight_norms": 0,
  "sdxl": false,
  "sdxl_cache_text_encoder_outputs": false,
  "sdxl_no_half_vae": false,
  "seed": 0,
  "shuffle_caption": false,
  "stop_text_encoder_training": 0,
  "text_encoder_lr": 0.0001,
  "train_batch_size": 1,
  "train_data_dir": "/Users/kakakikikeke/Downloads/data",
  "train_norm": false,
  "train_on_input": true,
  "training_comment": "",
  "unet_lr": 0.0001,
  "unit": 1,
  "up_lr_weight": "",
  "use_cp": false,
  "use_scalar": false,
  "use_tucker": false,
  "v2": false,
  "v_parameterization": false,
  "v_pred_like_loss": 0,
  "vae": "",
  "vae_batch_size": 0,
  "wandb_api_key": "",
  "wandb_run_name": "",
  "weighted_captions": false,
  "xformers": "none"
}

Stable Diffusion WebUI で生成

あとは sd-webui で生成するだけです
sd-scripts で生成した LoRA を指定しプロンプトで生成します
プロンプトは以下です

realistic, 1boy, solo, male focus, day, teeth, blue eyes, black hair, polka dot shirt, upper body, shirt, smile, portrait, kakakikikeke, simple background	<lora:kakakikikeke:1>

また生成時のパラメータは以下だけいじっています

Sampling method -> Euler a
Sampling steps -> 30
Batch count -> 12

で、できあがった画像が以下

手が3本あったりします

考察

おそらくもっと学習データを増やせばもっと精度が良くなると思います
学習させたデータが同じ向きしかないのともともと画像がかなり荒いので生成される画像も少しかけ離れた感じになってしまいます
学習させたデータが上半身しかないのでそれも微妙だった気がします、できれば全身のいろいろな角度の写真が望ましかったかもしれません

また LoRA 学習時のタグ生成ももう少し工夫すればプロンプトにうまく反映できるようになるのかなと思います

あとはプロンプトでリアルな人間を生成する感じのプロンプトを付与すればもっとリアルな感じになるのかなと思います

(masterpiece,best quality:1.4),(8k,raw photo,photo realistic:1.2)

ベースのモデルをデフォルトのやつではなく日本人の顔に特化したモデルに変更してももっと良い結果になるかもしれません

最後に

たった一枚の写真でもここまで生成に反映できるとは思いませんでした
現在の年齢の写真や幼少期の写真も学習させれば生まれてから現在はたまた未来の自分までの画像が作成できるかもしれません

今回環境が M2 mac mini だったので学習させる画像の量に限界があるのがネックです
もし大量の画像を学習させていろんなバリデーションの自分を出力できるようにするのであればそれなりのスペックのマシンか Google Colab あたりで動作させる必要があるかもです

2024年5月10日金曜日

AI kakakikikeke に Tomorrow never knows を歌わせてみた

AI kakakikikeke に Tomorrow never knows を歌わせてみた

今流行りの AI による歌を自分で作成してみました

できたもの

うぉっおーの高音部分が出てないところがまたリアル

環境

  • macOS 14.4.1 (M2Pro Mac mini)
  • Python 3.9.18
  • RVC WebUI (updated1006v2)

作り方

流れは以下の感じです

  1. 自分の音声モデルの作成
  2. 音源のBGMと声の分割
  3. 分割した声のファイルと音声モデルを使って推論
  4. BGMと推論により作成された音源ファイルを合成

です
なお使用したツールは RVC と Audacity になります

自分の音声モデルの作成

自分の声はこれまで Podcast でしこたま録音しているのでそれを使いました
たくさんあったほうがいいのですが 20 分くらいあれば十分っぽいのでこれを使いました

これを使って RVC の Train 機能を使って音声モデルを作成するだけです
モデルを生成する際はいろいろとチューニング可能なのでそれによっても歌い方がだいぶ変わってきます

harvest は品質が良くなりますがかなり学習に時間がかかります

音源のBGMと声の分割

今回は Mr.Children さんの Tomorrow never knows を音源として使わせていただきます
特に理由はないですがただただ好きなだけです
あとは男性の音声モデルの場合は男性の音源を使うほうが精度が良いかなと思ったので男性ボーカルの歌を選択しました

分割した声のファイルと音声モデルを使って推論

音声モデルファイルは pytorch 形式で出力されます
このモデルを使って分割したボーカルのみのファイルに自分の声とボイスチェンジを行うのが推論になります

推論が完成するとボーカルが自分の声になったバージョンの Tommorrow never knows が完成します

ここでも harvest は品質が良くなりますがかなり推論に時間がかかります
今回は crape を使っています (一番良さそうだったので

また途中 BGM を歌っている部分があったのでそこもカットしています

合成する

あとは分割した BGM 部分と自分の声になったボーカルファイルを合成するだけです
これは RVC ではなく普通の DTM ソフトを使います
自分は Audacity を使いました

最後に

高音部分を学習させてあげれば更によくなるかもです

これで僕が死んでからも音声モデルさえ残しておけば僕の声を聞くことができるようになりました
M2 Mac mini を購入してから AI 関連の高負荷処理も簡単にさばけるようになったので AI 関連の作業が楽ちんです

参考サイト

2024年3月3日日曜日

iPhone14 デビュー

iPhone14 デビュー

前回の iPhoneXR から 1698 日 (4年と238日) 経過して iPhone14 に乗り換えました
久しぶりに良いかものだったかなと

料金

中古で 82980 円

  • ポイントで 16038 + 5,808 使用
  • 支払い金額は 61134 円

バッテリー残量

  • 100%

まさかの 100% でした (ラッキー
ちなみに iPhoneXR 時代はバッテリーを 1 回だけ換装しています
というか外観もほぼ傷なしで間違って新品を送ってしまったのではないかと勘違いする感じでした

スペック

  • iPhone14 Midnight 128GB
    • Model A2881
    • SIMフリー

付属品

当然全部なしです (箱、充電ケーブル、説明書

あとは個別にフィルムだけ購入しています

引き継ぎについて

  • 基本は iPhone の引き継ぎをすれば OK (モワモワを撮影するやつ
    • iCloud 経由ではなく直接転送
    • 設定は基本全部デフォルト
    • iOS も最新にアップデート
    • Apple Pay、エクスプレスカードやデフォルトの支払いが変わっている可能性がある
    • Apple ID
    • オートメーションやスイッチコントロール、Music 内の音楽も引き継いでくれる
  • 各種アプリのログインし直し
    • 引き継ぎが個別で必要なアプリは別途やる必要あり
    • また設定が引き継がれないアプリもあるので
  • SIM カード入れ替え
    • mineo の APN は引き継がれる模様
    • 引き継ぎ作業が終わってからでも OK
  • 引き継ぎ後の iPhoneXR は速攻ファクトリリセットした

ネットワークの関係もあるので全部含めて 1 時間くらいはかかりました
アプリのインストールは引き継ぎ後一気に行われるので Wifi 配下でやりましょう (モバイル通信だとあっという間に上限にいくはず

所感

  • XR より軽い
  • XR よりサクサク
  • 気分が上がる
  • A15 bionic は iPhone13 も使っているのでそっちの性能も気になる

最後に

やはり iPhone の寿命は 5 年なのだろうか

2024年2月19日月曜日

M2Pro mac mini お掃除

M2Pro mac mini お掃除

購入 から半年以上経過したのでお掃除しました

道具

  • トルクドライバー
  • プラスチックヘラ

ほこりはエアダスターで飛ばすか拭き取るか掃除機を使いましょう

底盤を開ける

ヘラを入れて一周するだけです

更にアルミの底盤を外す

ネジが六ヶ所あります
写真では掃除後ですがここだけでもかなり汚かったです

アルミの底盤を外すときの注意

Wifi モジュールのケーブルが繋がっているのでヘラとトルクネジを使って外しましょう
いきなり底盤を外そうとするとケーブルが切れる可能性があるので注意してください

アルミ盤の裏

こっちも汚れているのでお掃除しましょう

底盤開けた後

汚いです

ファンを外す

かなり汚れています
トルクドライバーで4箇所のネジを外します

ファンを外すときの注意

ファンの動力のケーブルが繋がっているのでヘラを使って外しましょう
引っ掛けて上にパキっと外す感じです
iPhone のコネクタっぽい感じです

エアダスターで掃除

もっと解体できますがエアダスターがあればここまででも十分かなと思います
エアダスターで万全なく掃除しましょう
ほこりが舞うので掃除機で吸うなり換気のいい場所でやるなりしてください

ファンは解体できなかった

ファンにもプラスネジがありこれを外せば蓋を外せるかなと思ったのですが固くて外せませんでした
これもエアダスターを吹きかけて掃除しましょう
かなりほこりが出てくるので注意してください

あとは戻すだけ

各種掃除したらファン -> アルミ -> 底盤で戻します
各種コネクタの取り忘れに注意しましょう

最後に

毎日 CPU フル回転だと半年ごとくらいにこれくらいの掃除はしないと大変なことになりそうな気がします

2024年2月15日木曜日

iOS 版スイカゲームプレイメモ

iOS 版スイカゲームプレイメモ

おもしろい

料金

  • 240円

最高点

  • 3117点

プレイできた端末

  • iPhoneXR (iOS 17.2.1)
  • iPhone6 (iOS 12.5.7)
  • iPad min 2 (iOS 12.5.7)

という感じでまだまだ古い端末でも全然プレイできました
これがスイカゲームの一番良いところかもしれない

ただなぜか iPad mini 2 だけゲーム終了時に確実にクラッシュするという現象が発生したのが残念な点

コツ

  • とにかくゴミを出さない
  • 大きいのは下
  • 段差を使った時間差落下を使う (あとに落としたフルーツが先に落下する技術?
  • 連鎖も少し考えるといいかも
  • あとはとにかくやるだけ楽しいから全然飽きない

よかった点

  • iOS12 のサポートがある
  • 一応オフライン状態でもできる
  • 子供も楽しめる
  • クセになる

最後に

スイカを 2 つ作るのはマジで無理ゲー