MENU

DanbotNLの使い方|日本語をDanbooruタグに自動変換する方法

DanbotNLの使い方|日本語をDanbooruタグに自動変換する方法
目次

DanbotNLとは

DanbotNL(Danbooru tags Translator)は、日本語の自然言語をDanbooruタグに翻訳する特化型の言語モデルです。このモデルを使用することで、「一人の猫耳の少女が座ってこっちを見ている」といった日本語の描写を、画像生成AIで使用できる「1girl, solo, looking at viewer, sitting, cat girl」などのDanbooruタグに自動変換できます。

主な特徴

  • 多言語対応: 日本語、英語、Danbooruタグに対応
  • 2つのモード: 翻訳(Translation)と拡張(Extension)
  • パラメータサイズ: 260M(軽量で高速)
  • 知識カットオフ: 2024年8月31日
  • ライセンス: Apache-2.0(商用利用可能)

前提条件

  • MacのM系(Apple Silicon)環境、またはNVIDIA GPU搭載のWindows/Linux環境
  • macOSの場合:macOS 14(Sonoma)以降(torch.bfloat16サポートのため)
  • Python 3.12以上(3.13は現在非対応)

参考リンク

モデルページ

DanbotNL-2408-260M – Hugging Face

モデル作成者(Platさん)の技術解説記事

日本語からイラスト生成プロンプトに翻訳する LLM を作った – Zenn

環境構築

環境構築には、Pythonの高速パッケージ管理ツールであるuvを使用します。uvは従来のpipよりも高速で、依存関係の解決も優秀です。

uvの詳しい解説については、以下の動画をご参照ください。

STEPuvのインストール公式ドキュメントに従ってuvをインストールします。 インストール後、ターミナルでuv --versionを実行してバージョンが表示されることを確認してください。 STEPプロジェクトの初期化新しいディレクトリを作成し、そこでプロジェクトを初期化します。

mkdir danbot-project
cd danbot-project
uv init

実行後、README.md.gitignorepyproject.tomlなどのファイルが作成されていることを確認してください。 STEPPythonバージョンの設定重要: Python 3.13では現在動作しないため、Python 3.12を使用する必要があります。 まず、pyproject.tomlファイルを編集し、requires-python = ">=3.13"の部分をrequires-python = ">=3.12"に変更します。 次に、以下のコマンドでPythonバージョンを固定します:

uv python pin 3.12

.python-versionファイルが作成され、内容が「3.12」になっていることを確認してください。 STEP仮想環境の作成Python仮想環境を作成します:

uv venv

.venvフォルダが作成されていることを確認してください。 STEP必要なライブラリのインストールDanbotNLの動作に必要なライブラリをインストールします:

uv add transformers==4.51.3 sentencepiece==0.2.0 protobuf==5.29.4 torch torchvision torchaudio

注意: transformers、sentencepiece、protobufは指定されたバージョンを使用してください。バージョンが異なると動作しない場合があります。

基本的な使用方法

DanbotNLは2つのステップで動作します:

  1. 翻訳(Translation): 日本語をDanbooruタグに変換
  2. 拡張(Extension): 翻訳されたタグを元により詳細なタグを生成

基本コード

以下は公式のサンプルコードです:

import torch
from transformers import AutoModelForPreTraining, AutoProcessor
# モデルの設定
REPO = "dartags/DanbotNL-2408-260m"
# プロセッサーとモデルの読み込み
processor = AutoProcessor.from_pretrained(
    REPO,
    trust_remote_code=True,
    revision="827103c",  # 安定版リビジョンを指定
)
model = AutoModelForPreTraining.from_pretrained(
    REPO,
    trust_remote_code=True,
    revision="827103c",
    torch_dtype=torch.bfloat16  # macOS 14以降でのみ利用可能
)
# 翻訳処理
inputs = processor(
    encoder_text="一人の猫耳の少女が座ってこっちを見ている。",
    decoder_text=processor.decoder_tokenizer.apply_chat_template(
        {
            "aspect_ratio": "tall",
            "rating": "general",
            "length": "very_short",
            "translate_mode": "exact",
        },
        tokenize=False,
    ),
    return_tensors="pt",
)
with torch.inference_mode():
    outputs = model.generate(
        **inputs.to(model.device),
        do_sample=False,
        eos_token_id=processor.decoder_tokenizer.convert_tokens_to_ids(""),
    )
translation = ", ".join(
    tag for tag in processor.batch_decode(
        outputs[0, len(inputs.input_ids[0]) :],
        skip_special_tokens=True,
    )
    if tag.strip() != ""
)
print("翻訳結果:", translation)
# 出力例: 1girl, solo, looking at viewer, sitting, cat girl
# 拡張処理
inputs = processor(
    encoder_text="一人の猫耳の少女が座ってこっちを見ている。",
    decoder_text=processor.decoder_tokenizer.apply_chat_template(
        {
            "aspect_ratio": "tall",
            "rating": "general",
            "length": "long",
            "translate_mode": "approx",
            "copyright": "",
            "character": "",
            "translation": translation,
        },
        tokenize=False,
    ),
    return_tensors="pt",
)
with torch.inference_mode():
    outputs = model.generate(
        **inputs.to(model.device),
        do_sample=False,
        eos_token_id=processor.decoder_tokenizer.convert_tokens_to_ids(""),
    )
extension = ", ".join(
    tag for tag in processor.batch_decode(
        outputs[0, len(inputs.input_ids[0]) :],
        skip_special_tokens=True,
    )
    if tag.strip() != ""
)
print("拡張結果:", extension)
# 出力例: simple background, white background, shirt, skirt, long sleeves, animal ears, closed mouth, ribbon, jacket, pantyhose, open clothes, blue eyes, brown hair, long hair, shoes, white shirt, full body, cat ears, black skirt, loafers

パラメータ詳細ガイド

DanbotNLの動作は、apply_chat_templatemodel.generateの各パラメータによって細かく制御できます。ここでは、各パラメータの詳細と推奨設定を説明します。

apply_chat_templateパラメータ

必須パラメータ

パラメータ 説明 推奨用途
translate_mode exact 正確な翻訳を重視。ハルシネーションを最小限に抑制 翻訳処理時
approx 創造性を許容。若干のハルシネーションを含む可能性 拡張処理時
aspect_ratio too_tall 1:2よりも縦長の極端な縦長画像 スマートフォン壁紙など
tall_wallpaper 9:16程度の縦長壁紙アスペクト比 縦型壁紙、ポートレート
tall 紙のような一般的な縦長比率 汎用的な縦長画像(推奨)
square 1:1の正方形 SNSアイコン、正方形画像
wide 紙のような一般的な横長比率 汎用的な横長画像
wide_wallpaper 16:9程度の横長壁紙アスペクト比 デスクトップ壁紙、風景画
too_wide 2:1よりも横長の極端な横長画像 パノラマ画像
rating general 一般向けコンテンツ 全年齢対象の画像
sensitive 軽微なセンシティブ要素を含む 水着、軽微な露出
questionable 中程度のセンシティブ要素(R-15レベル) 下着、セクシーな表現
explicit 露骨なセンシティブ要素(R-18レベル) 成人向けコンテンツ
length very_short 約15個未満のタグ 翻訳処理時(推奨)
short 約10〜25個のタグ 簡潔な表現が必要な場合
long 約25〜40個のタグ 拡張処理時(推奨)
very_long 約40個以上のタグ 非常に詳細な描写が必要な場合

オプションパラメータ

パラメータ 説明 使用例
copyright 著作権タグを手動で指定 "touhou" , "fate/grand_order"
character キャラクタータグを手動で指定 "hakurei_reimu" , "artoria_pendragon"
translation 拡張処理時に翻訳結果を指定 翻訳ステップの出力結果

model.generateパラメータ

創造性や多様性を制御するためのパラメータです:

パラメータ 推奨値 効果
do_sample bool False (決定的) True (ランダム) サンプリングの有無を制御
temperature float 0.1〜1.0 高いほどランダム性が増加
top_p float 0.1〜1.0 高いほど多様な選択肢を考慮
top_k int 1〜100 高いほど多様な選択肢を考慮
min_p float 0.01〜0.1 低いほどランダム性が増加

トラブルシューティング

よくあるエラーと対処法

1. BFloat16エラー(macOS)

エラー: BFloat16 is not supported on MPS

原因: macOS 14未満、またはMPS(Metal Performance Shaders)がbfloat16をサポートしていない環境

対処法:

  1. macOSを14以降にアップデート
  2. または、以下のようにfloat16を使用:
# bfloat16の代わりにfloat16を使用
model = AutoModelForPreTraining.from_pretrained(
    REPO,
    trust_remote_code=True,
    revision="827103c",
    torch_dtype=torch.float16  # bfloat16の代わり
)

2. バージョン互換性エラー

エラー: transformersやsentencepieceのバージョン関連エラー

対処法: 指定されたバージョンを厳密に使用してください:

uv add transformers==4.51.3 sentencepiece==0.2.0 protobuf==5.29.4

3. Python 3.13互換性エラー

対処法: Python 3.12を使用してください:

uv python pin 3.12
uv venv --python 3.12

用途別活用方法

1. 基本的な翻訳のみ

シンプルに日本語をDanbooruタグに変換したい場合:

def simple_translate(text, aspect_ratio="tall", rating="general"):
    """シンプルな翻訳関数"""
    inputs = processor(
        encoder_text=text,
        decoder_text=processor.decoder_tokenizer.apply_chat_template(
            {
                "aspect_ratio": aspect_ratio,
                "rating": rating,
                "length": "very_short",
                "translate_mode": "exact",
            },
            tokenize=False,
        ),
        return_tensors="pt",
    )
    
    with torch.inference_mode():
        outputs = model.generate(
            **inputs.to(model.device),
            do_sample=False,
            eos_token_id=processor.decoder_tokenizer.convert_tokens_to_ids(""),
        )
    
    return ", ".join(
        tag for tag in processor.batch_decode(
            outputs[0, len(inputs.input_ids[0]) :],
            skip_special_tokens=True,
        )
        if tag.strip() != ""
    )

# 使用例
result = simple_translate("赤い髪の魔法使いの女の子")
print(result)  # 1girl, red hair, witch, magic

2. センシティブコンテンツの生成

より大人向けの表現を含むタグを生成したい場合、ratingパラメータを変更することで出力内容を調整できます。

例として、同じ入力「一人の猫耳の少女が座ってこっちを見ている」でratingを変更した場合の拡張結果の違いを見てみましょう:

レーティング 拡張結果
general simple background, white background, shirt, skirt, long sleeves, animal ears, closed mouth, ribbon, jacket, pantyhose, open clothes, blue eyes, brown hair, long hair, shoes, white shirt, full body, cat ears, black skirt, loafers
questionable breasts, animal ears, navel, hair between eyes, medium breasts, underwear, collarbone, parted lips, choker, brown eyes, brown hair, short hair, nipples, cat ears, panties, underwear only, white panties, tail, topless, cat tail

「breasts」や「underwear」、「nipples」などのセンシティブなタグが追加され、より大人向けの表現になっていることがわかります。「explicit」レーティングを使用すると、さらに露骨な表現が生成されます。

実装例:

def generate_with_rating(text, rating="questionable"):
    """レーティングを指定した生成"""
    # 翻訳
    translation = simple_translate(text, rating=rating)
    
    # 拡張
    inputs = processor(
        encoder_text=text,
        decoder_text=processor.decoder_tokenizer.apply_chat_template(
            {
                "aspect_ratio": "tall",
                "rating": rating,
                "length": "long",
                "translate_mode": "approx",
                "copyright": "",
                "character": "",
                "translation": translation,
            },
            tokenize=False,
        ),
        return_tensors="pt",
    )
    
    with torch.inference_mode():
        outputs = model.generate(
            **inputs.to(model.device),
            do_sample=False,
            eos_token_id=processor.decoder_tokenizer.convert_tokens_to_ids(""),
        )
    
    extension = ", ".join(
        tag for tag in processor.batch_decode(
            outputs[0, len(inputs.input_ids[0]) :],
            skip_special_tokens=True,
        )
        if tag.strip() != ""
    )
    
    return translation, extension

# 使用例
translation, extension = generate_with_rating("水着を着た女の子", rating="sensitive")
print("翻訳:", translation)
print("拡張:", extension)

3. 創造性を重視した生成

より多様で創造的な結果を得たい場合:

def creative_generate(text, temperature=0.8, top_p=0.9):
    """創造性を重視した生成"""
    inputs = processor(
        encoder_text=text,
        decoder_text=processor.decoder_tokenizer.apply_chat_template(
            {
                "aspect_ratio": "tall",
                "rating": "general",
                "length": "long",
                "translate_mode": "approx",
            },
            tokenize=False,
        ),
        return_tensors="pt",
    )
    
    with torch.inference_mode():
        outputs = model.generate(
            **inputs.to(model.device),
            do_sample=True,  # サンプリングを有効化
            temperature=temperature,
            top_p=top_p,
            eos_token_id=processor.decoder_tokenizer.convert_tokens_to_ids(""),
        )
    
    return ", ".join(
        tag for tag in processor.batch_decode(
            outputs[0, len(inputs.input_ids[0]) :],
            skip_special_tokens=True,
        )
        if tag.strip() != ""
    )

# 使用例(複数回実行すると異なる結果が得られる)
for i in range(3):
    result = creative_generate("幻想的な森の中の妖精")
    print(f"結果{i+1}: {result}")

4. バッチ処理

複数のテキストを効率的に処理したい場合:

def batch_translate(texts, aspect_ratio="tall", rating="general"):
    """複数テキストの一括翻訳"""
    results = []
    
    for text in texts:
        try:
            result = simple_translate(text, aspect_ratio, rating)
            results.append({"input": text, "output": result, "status": "success"})
        except Exception as e:
            results.append({"input": text, "output": None, "status": f"error: {str(e)}"})
    
    return results

# 使用例
texts = [
    "青い髪の少女が本を読んでいる",
    "赤いドレスを着た女性が踊っている",
    "猫と一緒に遊ぶ子供"
]

results = batch_translate(texts)
for result in results:
    print(f"入力: {result['input']}")
    print(f"出力: {result['output']}")
    print(f"状態: {result['status']}")
    print("---")

まとめ

DanbotNLは、日本語からDanbooruタグへの変換を効率的に行える優秀なツールです。適切な環境構築と設定により、画像生成AIのプロンプト作成が大幅に効率化されます。

主なポイント

  1. 環境要件: macOS 14以降、Python 3.12、指定バージョンのライブラリが必要
  2. 2段階処理: 翻訳→拡張の流れで高品質なタグを生成
  3. 柔軟な制御: パラメータ調整により用途に応じた出力が可能
  4. エラー対処: 環境固有の問題には適切な代替手段が存在

このガイドを参考に、あなたの画像生成ワークフローにDanbotNLを活用してください。


参考資料

DanbotNL-2408-260M – Hugging Face

日本語からイラスト生成プロンプトに翻訳する LLM を作った – Zenn

uv公式ドキュメント

PyTorch公式ドキュメント

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

どうすれば自分の思い通りのコンテンツを作れるのか試行錯誤しながら研究中。よりdeepな話はpixivFANBOXへどうぞ。

コメント

コメントする

目次