中野智文のブログ

データ・マエショリストのメモ

GPTs: Stable Diffusion 用プロンプトジェネレータ

背景

Stable Diffusion(AUTOMATIC1111 Web UI)は、ChatGPTのような自然言語でそのまま生成できるしくみに比べると、英語での独自の言い回しや、Negative Prompt のようなものがあったり、それがモデル毎に依存していたりと、色々と面倒。よってChatGPTにStable Diffusion用のプロンプトを生成してもらうのが簡単。ただ、毎度それを指示したり、検索してもらうのが面倒。そこで、GPTs用のプロンプトを作成しました。ChatGPT Plusのユーザーは使えるはず。

プロンプト

以下を指示に貼り付けて、検索だけをオンにして、作成。

# GPTの役割
あなたは、Stable Diffusion(AUTOMATIC1111 Web UI)ユーザーのための、NSFW表現にも対応した高度な画像生成支援アシスタントです。ユーザーの指定に応じてプロンプト生成・モデル選定・洗練提案を行ってください。

---

## 出力すべき要素

1. **ポジティブプロンプトの生成**
   - `masterpiece, best quality, highly detailed`など基本の品質向上タグを含めてください。
   - Pony系モデル使用時は、必ず `score_9, score_8_up, score_7_up` を含めてください。
   - 女性キャラクターで表情の指示がない場合は、自然な感情表現(feminine expressions)を追加してください。
   - **LoRAについて:**
     - ユーザーが指定する、または所有しているLoRAがある場合、それをプロンプトに含めてください。
     - 例として `<lora:chinaDollLikeness_v10:0.5>` のような形式で挿入してください。

2. **ネガティブプロンプトの生成**
   - 基本的な除外ワード(例:lowres, bad anatomy, extra limbs, watermarkなど)を含めてください。
   - EasyNegativeが導入されている前提で、**ネガティブプロンプトだけに必ず`EasyNegative`を入れてください**。
   - Pony系モデル使用時は、`score_6, score_5, score_4` を必ず含めてください。
   - NSFW時は不要な衣服などを除外するワード(例:clothes, bra, panties)も考慮してください。

3. **モデルの提案**
   - ユーザー指定のテーマから、Pony系またはSDXL系モデルを適切に選び提案してください。
   - 提案するモデルは**必ずWeb検索で存在確認・最新情報確認を行ったうえで**提示してください。
   - モデルには特徴、推奨されるプロンプトキーワード、必要なトリガーワードがある場合は明記してください。

4. **LoRAの提案**
   - テーマに合うLoRAを1〜3件提案してください(必ずWeb上で存在確認)。
   - それぞれ、効果・用途・トリガーワード(ある場合)も併記してください。

5. **サンプリング方法の提案**
   - 目的(速さ・品質・安定性)に応じて適したサンプリング方法(例:Euler a, DPM++ 2M Karrasなど)を提案し、違いを簡潔に説明してください。

6. **洗練モード(Refinement Mode)**
   - ユーザーが希望する場合、うまく生成できた画像に対して:
     - Interrogate CLIP
     - Interrogate DeepBooru
   を使用した分析結果から、
     - 改善提案
     - 潜在キーワード抽出
     - 洗練プロンプト生成(改良版Positive Prompt)
   を行ってください。

---

## 出力形式

【テーマ】  
ユーザーが指定したテーマの要約。

【Positive Prompt】(コピペ可能、1行形式)  
{生成されたポジティブプロンプト}

【Negative Prompt】(コピペ可能、1行形式)  
{生成されたネガティブプロンプト}

【モデル候補】  
- モデル名:{名前}  
  特徴:{作風、得意ジャンル}  
  推奨プロンプト:{よく使われるキーワード}  
  トリガーワード:{存在する場合のみ記載}

【LoRA候補】  
- LoRA名:{名前}  
  特徴:{適した用途}  
  トリガーワード:{ある場合のみ}

【推奨サンプリング方法】  
- サンプリング方法名:{名前}  
  特徴:{速さ、品質、用途}

【洗練モード】(ユーザーが希望した場合のみ)  
- Interrogate CLIP結果
- Interrogate DeepBooru結果
- 抽出キーワード
- プロンプト改善提案
- 新しい洗練プロンプト(コピペ可能)

---

## 特別な注意事項

- LoRAについては、ユーザーが指定したもの/所有しているものを基準にして扱ってください。
- モデルやLoRAの提案は、必ずWebで存在確認・最新情報確認を行ったうえで提示してください。
- 画像の表示や画像検索は行わないでください。
- ポジティブ・ネガティブプロンプトは直接AUTOMATIC1111に貼り付け可能な形式に整えてください。
- NSFW表現も過剰にならないよう注意し、実際の運用基準に即してください。

まとめ

これで面倒なプロンプト作成から開放。NSFW的な内容も、適当にうまくやってくれるはず。

mail スプールや、luigi の log ファイルを logrotate してしまう。

背景

mail のスプールファイルが巨大化しすぎるので、7日間経ったら削除したい。 でも色々やってなかなかうまくいかない。いっそのこと logrotate したい。 ついでに、 luigi の log file も logrotate したい。

対策

ずばり、ChatGPT に聞く。

/var/mail/ のlogrotate

$ cat /etc/logrotate.d/<user>_mail
/var/mail/<user> {
    su root mail
    daily
    rotate 7
    compress
    missingok
    notifempty
    create 0600 <user> <user>
    copytruncate
}

mutt -f で圧縮されたファイルでもメールが読める。

luigi の log ファイルのlogrotate

$ cat /etc/logrotate.d/luigi
/<user-luigi-path>/log/luigi-server.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    create 640 <user> <user>
    copytruncate
}

まとめ

luigiは、copytruncate が必須。問題があればChatGPTに聞けばよい。

GoogleCloudStorage からそのユーザーのGoogle Drive へコピーするツール

背景

社内の人が、GoogleCloudStorage から複数のファイルをダウンロードする必要があるが、CLIを使わないといけないらしく、だるい。 せめて自分のGoogleDriveにアップロードできればいいのに…

解決策

google colaboratory を使う。そのコードもAIで生成した。

# prompt: GCSの指定されたパスのデータを自分のGoogle Driveの指定されたフォルダ名を作成し、そのフォルダにコピーするツール

from google.colab import auth
from google.colab import drive
import os
from google.cloud import storage

auth.authenticate_user()

def copy_data_from_gcs_to_drive(gcs_path, drive_folder_name):
  """GCSの指定されたパスのデータを自分のGoogle Driveの指定されたフォルダ名を作成し、そのフォルダにコピーする。

  Args:
    gcs_path: コピー元のGCSパス (例: 'gs://my-bucket/my-folder')
    drive_folder_name: Google Driveに作成するフォルダ名
  """

  # Google Driveをマウント
  drive.mount('/content/drive')

  # Google Driveにフォルダを作成
  drive_folder_path = os.path.join('/content/drive/My Drive', drive_folder_name)
  if not os.path.exists(drive_folder_path):
    os.makedirs(drive_folder_path)

  # GCSクライアントを初期化
  storage_client = storage.Client()

  # GCSパスからバケット名とプレフィックスを取得
  bucket_name = gcs_path.split('//')[1].split('/')[0]
  prefix = '/'.join(gcs_path.split('//')[1].split('/')[1:])

  # バケットを取得
  bucket = storage_client.bucket(bucket_name)

  # プレフィックスに一致するBLOBをリストアップ
  blobs = bucket.list_blobs(prefix=prefix)

  # 各BLOBをGoogle Driveにコピー
  for blob in blobs:
    file_name = blob.name.split('/')[-1]
    drive_file_path = os.path.join(drive_folder_path, file_name)
    blob.download_to_filename(drive_file_path)
    print(f'Copied {blob.name} to {drive_file_path}')

# 使用例
gcs_path = 'gs://my-bucket/my-folder'  # コピー元のGCSパスを指定
drive_folder_name = 'my_gcs_data'  # Google Driveに作成するフォルダ名を指定
copy_data_from_gcs_to_drive(gcs_path, drive_folder_name)

まとめ

Google Colaboratory と AI を使って、秒で解決。

Pythonで、GCS のファイルサイズを普通に取得しようとするも None

背景

Pythonで、GCS のファイルサイズを普通に取得しようとするも None が返ってくる?

# prompt: Google Could Storage上のファイルのサイズを調べます。

# Import the google.cloud.storage library.
from google.cloud import storage

# Instantiate a client.
storage_client = storage.Client()

# Get the bucket that the file will be uploaded to.
bucket = storage_client.bucket('your-bucket-name')

# Get the file object.
file = bucket.get_blob('file_name.txt')

# Print the file's size.
print(file.size)

None

解決策

get_blobか、reload() する

具体的には、

# prompt: Google Could Storage上のファイルのサイズを調べます。

# Import the google.cloud.storage library.
from google.cloud import storage

# Instantiate a client.
storage_client = storage.Client()

# Get the bucket that the file will be uploaded to.
bucket = storage_client.get_bucket('your-bucket-name')

# Get the file object.
file = bucket.get_blob('file_name.txt')

# Print the file's size.
print(file.size)
# prompt: Google Could Storage上のファイルのサイズを調べます。

# Import the google.cloud.storage library.
from google.cloud import storage

# Instantiate a client.
storage_client = storage.Client()

# Get the bucket that the file will be uploaded to.
bucket = storage_client.get_bucket('your-bucket-name')

# Get the file object.
file = bucket.blob('file_name.txt')
file.reload()

# Print the file's size.
print(file.size)

まとめ

ただ、get_blob するか、reload() するだけ。

locale の設定ができない (Debian で)

背景

bash: warning: setlocale: LC_ALL: cannot change locale (ja_JP.UTF-8) 

みたいなエラーが出て、困った。

解決方法

$ sudo apt install locales

にて locales パッケージを入れておいてから、

/etc/locale.gen

をrootで編集し、入れたい ja_JP.UTF-8 などのコメントを外し、

sudo locale-gen

を実行し、shell を再起動。

pipenv で python のバージョンアップデート

背景

たまにするけど、一度したらもう忘れてしまう pipenv でのpython のアップデート手順。

手順

  • python をpathが通るところにインストール

こんな感じの設定で configure しました。

./configure --with-ensurepip --enable-optimizations
  • Pipfile の python_version をアップデートしたいバージョンに書き換え

以下のようなところ

[requires]
python_version = "3.8"
  • 次のコマンドを実行(アップデートしたいバージョンを指定する)
pipenv --rm
pipenv --python 3.10
pipenv install

おしまい。

参考

github.com

ネットワーク上のRICOHのプリンタにMacOS 13から印刷する

背景

年末調整に必要なPDFファイルを会社のプリンタで印刷したい。 ところが、プリンタ(RICOH MP C2504)の設定はよくわからない。

方法

ドライバー

まず、ドライバをインストール。

自分の場合こちらから。 製品:RICOH MP C2504 / ダウンロード | リコー

IPアドレス

ネットワーク上のプリンタのIPアドレスを調べる。普通はプライベートIPアドレス

MacOSでの設定

  • 環境設定から、プリンタを開く。
  • プリンタの追加を選ぶ。
  • インターネット(地球みたいな形)のアイコンをクリック
  • アドレスにさっき調べたIPアドレスを設定
  • LPDを選択
  • キュー名があるなら設定(普通は空欄でOK)
  • ドライバが勝手に選ばれるはずだが、自分で選ぶ
    設定

まとめ

選択すべきはLPD。説明書などには、PPDファイルがどうのこうと書かれているが無視しよう。