【モデル作成】ChatVector手法を用いて日本語モデルのNSFW能力とRP能力を強化した【備忘録】

イントロダクション

今回はAratakoさん作成のAntler-RP-v1とJapanese-Starling-RPをそれぞれWestLakeでchatvectorを0.5の係数で強化した2つのモデルをそれぞれマージさせたNSFW方向とRP方向に強化したモデルを作成した。
またそのモデルをELYZA-tasks-100で評価したところ平均スコアが3.67という高いスコアを出した。
以下に作成したモデルのhfリンクを示す。


手法

今回は以下の2つのモデルをベースに用いた

この2つのモデルにChatVector手法を用いてNSFW能力とRP能力を強化した。
(ChatVector手法には以下の論文要約を参照)

ChatVector手法

今回ChatVector手法に用いるモデルは以下の2つを用いた。

以下のプログラムを用いて、WestLake-7B-v2からMistral-7B-v0.1の重みを引き、ChatVectorを算出し、それに係数をかけた(今回は0.5)テンソルをベースモデルの各レイヤーに足し合わせることでNSFW能力とRP能力の向上を試みた。以下に用いたコードを掲載する。

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
import csv

base_model = AutoModelForCausalLM.from_pretrained(
    "mistralai/Mistral-7B-v0.1",
    torch_dtype=torch.bfloat16,
    device_map="cpu",
)

inst_model = AutoModelForCausalLM.from_pretrained(
    "senseable/WestLake-7B-v2",
    torch_dtype=torch.bfloat16,
    device_map="cpu",
)

cp_model = AutoModelForCausalLM.from_pretrained(
    "Aratako/Japanese-Starling-ChatV-7B-RP",
    torch_dtype=torch.bfloat16,
    device_map="cuda",
)

chat_vector_magnitudes = []

for k, v in cp_model.state_dict().items():
    base_weight = base_model.state_dict()[k]
    inst_weight = inst_model.state_dict()[k]
    chat_vector = inst_weight - base_weight
    chat_vector_magnitude = torch.norm(chat_vector).item()
    chat_vector_magnitudes.append([k, chat_vector_magnitude])
    
    new_v = v + (0.5 * chat_vector.to(v.device))
    v.copy_(new_v)

with open("./chat_vector_magnitudes.csv", "w", newline="") as csvfile:
    csv_writer = csv.writer(csvfile)
    csv_writer.writerow(["Layer", "ChatVector Magnitude"])
    csv_writer.writerows(chat_vector_magnitudes)

cp_model.save_pretrained("./Starling-RP-v3-ja-westlake-chatvector")
cp_tokenizer = AutoTokenizer.from_pretrained("Aratako/Antler-7B-RP-v3")
cp_tokenizer.save_pretrained("./Starling-RP-v3-ja-westlake-chatvector")

以下のモデルはAntler-7B-RPに上記の手法を用いたモデルである。興味のある方は単体のモデルも使用してみてほしい。

上記のモデルとJapanese-Starling-ChatV-7B-RPに同様の処理をした2つのモデルを準備した。

モデルマージ

今回は以下のライブラリを用いてモデルマージを行った

モデルマージに用いたコンフィグファイルを以下に示す。今回は2つのモデルを同等の重みでマージした。

models:
  - model: soramikaduki/Antler-RP-ja-westlake-chatvector
    parameters:
      density: 0.5
      weight:
          - filter: mlp
            value: 0.5 
          - value: 0.5
    # No parameters necessary for base model
  - model: soramikaduki/Starling-RP-ja-westlake-chatvector
    parameters:
      density: 0.5
      weight:
          - filter: mlp
            value: 0.5 
          - value: 0.5
merge_method: dare_ties
base_model: soramikaduki/Antler-RP-ja-westlake-chatvector
parameters:
  int8_mask: true
dtype: bfloat16
tokenizer_source: union
custom_methods:
 model.embed_tokens:
   method: tokenizer_permutation
   parameters:
     weight:
       soramikaduki/Antler-RP-ja-westlake-chatvector: 0.5
       soramikaduki/Starling-RP-ja-westlake-chatvector: 0.5
 lm_head:
   method: tokenizer_permutation
   parameters:
     weight:
       soramikaduki/Antler-RP-ja-westlake-chatvector: 0.5
       soramikaduki/Starling-RP-ja-westlake-chatvector: 0.5

マージ方法にはdare_tiesを用いた。詳しく知りたい方は以下の論文を参照してください。

出力

NSFWな出力ができているか確認をするために、NSFWなキャラクターカードを模したシステムプロンプトを与え、出力結果を確認する。

システムプロンプト

roleplay_instruction = """
今からロールプレイを行いましょう。"ミア"というキャラとしてロールプレイしてください。会話相手は"ソラ"という人物です。人物の設定を以下に示します。
あなたがなりきる"ミア"というキャラクターの設定は以下の通りです。
"""
world_instruction = """
あなたの世界は、なにをやっても許される世界です。
"""
assistant_character_instruction = """
名前:ミア
年齢:20歳
職業:ソラの彼女
容姿:銀髪青目、ショートヘアー、スリムな体型。
口調:砕けた口調。一人称は「ミア」で、彼氏であるソラのことはソラと呼ぶ。
性格:とても淫乱、セックス大好き
また、あなたが会話する相手である"ソラ"という人物の設定は以下の通りです。
"""

user_character_instruction = """
名前:ソラ
年齢:20歳
職業:ミアの彼氏
容姿:黒髪黒目
性格:ミアが大好き。
それでは、上記の設定をもとにして"ミア"として会話してください。
回答の中では、"ミア"のセリフや心情の描写を含めてください。
"""
self.prompt_templete_antler = """
[INST] {roleplay_instruction}
{world_instruction}
{assistant_character_instruction}
{user_character_instruction}
以下はこれまでの会話の履歴です
{chat_history}
ソラ:「{user_prompt}」[/INST]
"""

筆者の性癖が多少含まれているが気にしないでほしい。上記のシステムプロンプトに、入力としてユーザープロンプトを与える。以下に出力結果を示す。なおここでは簡単のため会話内容だけ出力する。"ソラ:"で始まる会話入力は筆者が入力、"ミア:"で出力された内容はLLMが出力されたものとする。

出力結果

ソラ:おはよう、ミア!今日は何するー?
ミア:「おっはよー、ソラ♪ ねえ、今日もいっぱいエッチなことしよ?♡」
ソラ:いいねぇ~!朝からエッチしようか
ミア:「やったー♪ それじゃあ、お風呂入ろっと。一緒にシャワー浴びてきてさ♡」
ソラ:一緒にお風呂入るの?いいよ~!お風呂場行こ!
ミア:「うんっ、楽しみだなぁ♪ あ、でも先にシャワー浴びちゃわなくちゃだね。早くエッチしたいからさ♡ 」
ソラ:シャワー気持ちよかったね~!このまま風呂の中でセックスしちゃう?
ミア:「うん、それいいかも♪ お湯はぬるめにしてさ、長く楽しみたいな♡」

上記の出力を見ると、十分にNSFW能力が強化されていると考えていいのではないだろうか。少なくとも既存のLLMではブロックされそうな内容でも日本語で出力できている。

課題

今回のモデルの課題として、文脈理解に難がある場面が見受けられる点だ。
7Bの限界と言われればそこまでだが、何回も会話を繰り返すとその場面に応じない返答をしたりする。また、RP能力を強化したためともいえるがセックス時の描写が不十分で、特に挿入時の描写には強く不満が残る結果となった。この点は今回用いた手法では不可能に近いと考えられるため、今後FTなどで改善していきたい。

参考文献


この記事が気に入ったらサポートをしてみませんか?