Llama-2が登場!8bit+LoRAでRLHFファインチューニングを試す方法はこちら

日本語版LIMAデータセットでopen-calm-7bをLoRAファインチューニングしてチャットボットを作成してみた

現代の自然言語処理(NLP)タスクにおいて、事前学習モデルは非常に重要な役割を果たしています。これらのモデルは、大量のテキストデータを使用してトレーニングされ、一般的な言語理解能力を獲得するための基礎を提供します。しかし、日本語のようなリソースが限られた言語においては、高品質の事前学習モデルの作成には課題があります。そのような中で近年、課題に取り組むために活用できるサイバーエージェントのopen-calm-7bが公開されています。

そこで、LoRA(Low-Rank Adaptation)と呼ばれる手法を用いて、open-calm-7bモデルを日本語LIMAデータセットでLoRAファインチューニングすることで、その精度向上を試みました。

LIMAの論文内で用いられたデータセットは、少数精鋭のデータセットとして知られています。

このデータセットを日本語訳したデータセットについては、こちらの記事を参照してください。

あわせて読みたい
日本語LIMAデータセットlima-jaを作成したので公開します 日本語LIMAデータlima-jaを作成しました! データセットをすぐに利用したい方はこちらから取得ください。 https://huggingface.co/datasets/zan/lima-ja 今回作成したデ...

以下の記事のような学習方法もあります。

あわせて読みたい
【Python】rinnaのGPT-2を使って個性を持つ会話の流れを保持して会話できるAI(chatbot)を作ってみた!... Dialogptやblenderbotを使ってボットを作りたいと思っても日本語の事前学習モデルが公開されていないのでなかなか個人には難しいですよね。そこで今回は、rinna社が公開している事前学習モデルを用いて誰でもできる方法を記事にしました。

(2023/07/20追記)

「Llama-2」が公開されました!

あわせて読みたい
【Llama-2】8bit+LoRAでRLHFファインチューニングを試す【学習できることは確認】 Llama-2が出たのでRLHFを試してみました。 事前学習モデルでは教師ありファインチューニングをしてから行う必要がありますが、すでに調整されているモデルが公開されて...
本記事で分かること
  • open-calm-7bのLoRAファインチューニング方法
  • モデルの推論結果
目次

ライブラリのインストール

今回用いるライブラリをインストールします。

Pytrochついてはご自分の環境に合わせて別でインストールしてください。

!pip install peft
!pip install transformers
!pip install datasets
!pip install accelerate
!pip install bitsandbytes

この中でbitsandbytesについては特にエラーが出る原因となりやすいと感じています。

学習が成功したバージョンを載せておきます。

accelerate==0.21.0.dev0
bitsandbytes==0.39.0
datasets==2.11.0
peft==0.4.0.dev0
transformers==4.27.4

上記以外にも私がもともと入れていたライブラリがあるかもしれないので随時入れてください。

実装コードの解説

以下の記事を参考にして改良を加えています。

ありがとうございました。

Qiita
OpenCALM-7BをLoRAでinstruction tuningするための実装解説 / QLoRAの実装も紹介 - Qiita はじめに※本記事で「現時点」という言葉は2023/6/1を指すこととします。先日(2023年5月17日)、サイバーエージェントが日本語に特化したLLM(Large Language Model)…
note(ノート)
Google Colab で PEFT による大規模言語モデルのファインチューニングを試す|npaka 「Google Colab」で 「PEFT」による大規模言語モデルのファインチューニングを試したので、まとめました。 1. PEFT 「PEFT」(Parameter-Efficient Fine-Tuning)は、モデ...

モデルとトークナイザーの読み込み

まずは、モデルとトークナイザーを読み込んでおきます。

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "cyberagent/open-calm-7b"
# トークナイザーの準備
tokenizer = AutoTokenizer.from_pretrained(model_name)
# モデルの準備
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    load_in_8bit=True,
    device_map="auto",
    torch_dtype=torch.float16
)
# 複数のGPUを使う場合
if torch.cuda.device_count() > 1:
    model.is_parallelizable = True
    model.model_parallel = True

複数のGPUを使う場合の設定もここでしておきます。

複数のGPUを使う方はこのコードがないと、学習時にRuntimeError: mat1 and mat2 shapes cannot be multiplied (722x28 and 27x4096)のようなエラーが出てしまいます。

データセットの読み込み

次にLIMA-JAデータセットを取得します。

from datasets import load_dataset
dataset = load_dataset('zan/lima-ja')

中身はこんな感じです。

>>> dataset["train"][0]
{'conversations': ['脳細胞は移動することができるのでしょうか? 移動とは、遠距離の移動(可能ならば脳内のみで)を指します。',
  'この質問は比較的広範であり、脳は単にニューロンだけでなく、グリア細胞(支持細胞)や前ミトーシスの神経幹細胞も含まれることを考慮する必要があります。さらに、重要な同僚科学者たちが指摘しているように、発生段階も非常に重要であり、発達中の胎児の脳は成人の脳とは非常に異なります。\n\nしかし、さまざまな出版物を精査した結果、この質問の答えは実際には非常に単純であることがわかりました。結論として、脳細胞は移動します。\n\n成人の脳では、グリア細胞が脳内を移動します(Klämbt、2009年)。グリア細胞は多くの機能に関与していますが、移動するグリア細胞の注目すべき例は、標的の軸索を見つけるために比較的長距離を移動し、それに巻きついて絶縁性のミエリン鞘を形成するオリゴデンドロサイトです(TsaiとMiller、2002年)。\n\n神経幹細胞は損傷に対応して長距離を移動します(Imitola et al.、2004年)し、特定の幹細胞の位置(例えば、海馬や脳室下帯)から他の領域に移動します(Clarke、2003年)。\n\nミトーシス後でありながら未分化のニューロンは、魚(Scott et al.、2012年)や哺乳類、および非人猿でも成人の脳内を移動することが示されています(Sawada et al.、2011年)。\n\n驚くことではありませんが、グリア細胞、幹細胞、およびニューロンは胎児の発生中も移動します。特に、末梢機能を果たすために運命づけられた分裂後のニューロンは、神経堤から標的の位置まで比較的長い距離を移動しなければなりません(Neuroscience、第2版、Neuronal Migration)。'],
 'source': 'stackexchange'}

内容はこんな感じです。

>>> dataset
DatasetDict({
    train: Dataset({
        features: ['conversations', 'source'],
        num_rows: 1030
    })
    test: Dataset({
        features: ['conversations', 'source'],
        num_rows: 300
    })
})

さらに今回は、ここでデータの長さを調整したいので2048トークンより長いデータは除きます。(学習時に2048トークン以上はエラーが出るためです。他の部分で処理をすれば大丈夫ですがここでやっておきます。)プロンプトのトークン分も除くべきですが、エラーは出なかったのでこのようにしています。

data_train = []
for i, item in enumerate(dataset["train"]):
    token = 0
    for j, c in enumerate(item["conversations"]):
        token += len(tokenizer.tokenize(c))
    if token <= 2048:
        data_train.append(item)

どれだけ減ったか見てみます。

>>> len(data_train)
1006

少し減っていますね。

扱えるトークン数を超えた部分は削る方法もありますが、完全な文章を学習させたかったのでこのようにしています。
この部分は、どのような方法でも大丈夫です。他の方法があればコメントで教えてください。

Datasetの準備

Datasetクラスを定義します。

from torch.utils.data import Dataset
from tqdm import tqdm

class ConversationDataset(Dataset):
    def __init__(self, json_list, tokenizer):
        # ConversationDatasetの初期化関数
        # json_list: JSON形式のデータリスト
        # tokenizer: トークナイザー
        self.tokenizer = tokenizer
        self.features = []
        all_texts_list = []

        # json_list内の各アイテムに対して処理を実行
        for item in tqdm(json_list):
            input_list = item["conversations"][:-1]
            output_text = item["conversations"][-1]
            input_text = "あなたはchatbotです。userと会話を行ってください。\n"
            
            # 入力リストの要素ごとに処理を実行
            for i, item in enumerate(input_list):
                # インデックスが偶数の場合はuserの発言を追加
                if i % 2 == 0:
                    input_text += f"\n### user:\n{item}\n"
                else:
                    # インデックスが奇数の場合はchatbotの発言を追加
                    input_text += f"\n### chatbot:\n{item}\n"
                    
            # chatbotの発言の欄を追加
            input_text += "\n### chatbot:\n"
            
            # 全てのテキストを結合し、トークナイザで処理
            all_text = input_text + output_text + self.tokenizer.eos_token
            all_texts_list.append(all_text)
        
        # トークナイズされたテキストのリストを特徴量として保存
        self.features = [
            tokenizer(
                text, padding=False, truncation=True, max_length=2048
            ) for text in tqdm(all_texts_list)
        ]
            
    def __len__(self):
        # データセットのサイズを返す
        return len(self.features)
    
    def __getitem__(self, idx):
        # 指定したインデックスの特徴量を返す
        return self.features[idx]

# インスタンスを作成
train_dataset = ConversationDataset(data_train, tokenizer)

このコードは、ConversationDatasetという名前のデータセットクラスを定義しています。主な機能は以下の通りです。

  • __init__: クラスの初期化関数です。引数としてJSON形式のデータリスト、トークを受け取ります。与えられたデータリストを処理し、トークナイズされたテキストのリストとして特徴量を作成します。
  • __len__: データセットのサイズ(特徴量の数)を返します。
  • __getitem__: 指定したインデックスの特徴量を返します。

具体的な処理は以下の通りです。

  • __init__関数では、与えられたJSONリストの各アイテムに対して以下の処理を実行します。
    • input_listには会話の最後の要素を除いた要素のリストが格納されます。
    • output_textには会話の最後の要素が格納されます。
    • input_textには最初のメッセージとして”あなたはchatbotです。userと会話を行ってください。\n”が格納されます。
    • input_list内の要素を順番に取り出し、偶数番目の要素は”user”の発言、奇数番目の要素は”chatbot”の発言としてinput_textに追加されます。
    • 最後に、”chatbot”の発言の欄を追加します。
    • 全てのテキストを結合し、トークナイザで処理されたテキストをall_texts_listに追加します。
    • all_texts_list内の各テキストに対してトークナイズを行い、特徴量としてself.featuresに保存します。
  • __len__関数では、特徴量の数を返します。
  • __getitem__関数では、指定したインデックスの特徴量を返します。

データの中身は以下のようになります。

>>> train_dataset[0]
{'input_ids': [7764, 1674, 899, 50143, 358, 247, 43302, 254, 5060, 44981, 247, 186, 186, 39843, ... 0],
 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ... 1]}

input_textの部分は自由に変えてもらって大丈夫です。この部分を変えるだけでもモデルの性能は変わってくると思います。
例:「あなたはchatbotです。userと会話を行ってください。\n」を「あなたは素晴らしいchatbotです。userと会話を行ってください。\n」に変える

collatorの準備

Collatorクラスを準備します。

from transformers import DataCollatorForLanguageModeling

collator = DataCollatorForLanguageModeling(tokenizer, mlm=False)

DataCollatorForLanguageModelingについてはData Collator (huggingface.co)をご覧ください。

学習を安定させる処理

学習を安定させるために一部をfloat32にキャストしたりレイヤーをフリーズしたりしています。

import torch.nn as nn

# モデルのパラメーターごとに、勾配の計算を無効にする
for param in model.parameters():
    param.requires_grad = False

    # パラメーターの次元が1次元の場合、データ型をtorch.float32に変換する
    if param.ndim == 1:
        param.data = param.data.to(torch.float32)

# モデルに勾配チェックポイントを有効化する
model.gradient_checkpointing_enable()

# モデルの入力に対する勾配の計算を有効化する
model.enable_input_require_grads()

# CastOutputToFloatという名前のクラスを定義し、nn.Sequentialクラスを継承する
class CastOutputToFloat(nn.Sequential):
    # forwardメソッドをオーバーライドし、入力データxに対してsuper()を呼び出して順伝搬を実行し、
    # 結果をtorch.float32のデータ型に変換して返す
    def forward(self, x):
        return super().forward(x).to(torch.float32)

# モデルのembed_out属性にCastOutputToFloatクラスのインスタンスを代入する
model.embed_out = CastOutputToFloat(model.embed_out)

この部分でもどこをフリーズするか、どこをfloat32にキャストするかなどを変更することでモデルの性能が変化すると思います。

LoRAの設定

LoRAにおけるパラメータなどを設定できます。

from peft import LoraConfig, get_peft_model, prepare_model_for_int8_training, TaskType

# LoRAのパラメータ
lora_config = LoraConfig(
    r= 8, 
    lora_alpha=16,
    target_modules=["query_key_value", "dense", "dense_h_to_4h", "dense_4h_to_h"],
    lora_dropout=0.05,
    bias="none",
    task_type=TaskType.CAUSAL_LM
)

# モデルの前処理
model = prepare_model_for_int8_training(model)

# LoRAモデルの準備
model = get_peft_model(model, lora_config)

# 学習可能パラメータの確認
model.print_trainable_parameters()

LoraConfigで設定できる引数の説明はこちらを参照してください。

あわせて読みたい

LoraConfigにおけるtarget_modulesはモデルによって設定できる名称が変わります。
モデルの構造を見ると分かります。長いです。
また、学習するパラメータ数も変化するので多く指定するとその分、学習時間も伸びます。
参考までに、”query_key_value”のみの場合epoch1あたり約15分、”query_key_value”, “dense”, “dense_h_to_4h”, “dense_4h_to_h”の場合は約25分でした。

モデル構造を表示する
>>> model
PeftModelForCausalLM(
  (base_model): LoraModel(
    (model): GPTNeoXForCausalLM(
      (gpt_neox): GPTNeoXModel(
        (embed_in): Embedding(52224, 4096)
        (layers): ModuleList(
          (0-31): 32 x GPTNeoXLayer(
            (input_layernorm): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)
            (post_attention_layernorm): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)
            (attention): GPTNeoXAttention(
              (rotary_emb): RotaryEmbedding()
              (query_key_value): Linear8bitLt(
                in_features=4096, out_features=12288, bias=True
                (lora_dropout): ModuleDict(
                  (default): Dropout(p=0.05, inplace=False)
                )
                (lora_A): ModuleDict(
                  (default): Linear(in_features=4096, out_features=8, bias=False)
                )
                (lora_B): ModuleDict(
                  (default): Linear(in_features=8, out_features=12288, bias=False)
                )
                (lora_embedding_A): ParameterDict()
                (lora_embedding_B): ParameterDict()
              )
              (dense): Linear8bitLt(
                in_features=4096, out_features=4096, bias=True
                (lora_dropout): ModuleDict(
                  (default): Dropout(p=0.05, inplace=False)
                )
                (lora_A): ModuleDict(
                  (default): Linear(in_features=4096, out_features=8, bias=False)
                )
                (lora_B): ModuleDict(
                  (default): Linear(in_features=8, out_features=4096, bias=False)
                )
                (lora_embedding_A): ParameterDict()
                (lora_embedding_B): ParameterDict()
              )
            )
            (mlp): GPTNeoXMLP(
              (dense_h_to_4h): Linear8bitLt(
                in_features=4096, out_features=16384, bias=True
                (lora_dropout): ModuleDict(
                  (default): Dropout(p=0.05, inplace=False)
                )
                (lora_A): ModuleDict(
                  (default): Linear(in_features=4096, out_features=8, bias=False)
                )
                (lora_B): ModuleDict(
                  (default): Linear(in_features=8, out_features=16384, bias=False)
                )
                (lora_embedding_A): ParameterDict()
                (lora_embedding_B): ParameterDict()
              )
              (dense_4h_to_h): Linear8bitLt(
                in_features=16384, out_features=4096, bias=True
                (lora_dropout): ModuleDict(
                  (default): Dropout(p=0.05, inplace=False)
                )
                (lora_A): ModuleDict(
                  (default): Linear(in_features=16384, out_features=8, bias=False)
                )
                (lora_B): ModuleDict(
                  (default): Linear(in_features=8, out_features=4096, bias=False)
                )
                (lora_embedding_A): ParameterDict()
                (lora_embedding_B): ParameterDict()
              )
              (act): GELUActivation()
            )
          )
        )
        (final_layer_norm): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)
      )
      (embed_out): CastOutputToFloat(
        (0): Linear(in_features=4096, out_features=52224, bias=False)
      )
    )
  )
)

Trainerの準備

transformersのTrainerを利用します。

import transformers

peft_name = "lora-calm-7b"
output_dir = "lora-calm-7b-output"

# トレーナーの準備
trainer = transformers.Trainer(
    model=model,
    train_dataset=train_dataset,
    args=transformers.TrainingArguments(
        num_train_epochs=1,
        learning_rate=3e-4,
        logging_steps=20,
        output_dir=output_dir,
        report_to="none",
        save_total_limit=1,
        push_to_hub=False,
        auto_find_batch_size=True,
    ),
    data_collator=collator,
)

Trainerの引数の詳しい説明はこちらを参照してください。

あわせて読みたい
Trainer We’re on a journey to advance and democratize artificial intelligence through open source and open science.

TrainingArgumentsについてはこちらです。

あわせて読みたい
Trainer We’re on a journey to advance and democratize artificial intelligence through open source and open science.

モデルの学習と保存

後は学習するだけです。

# 学習の実行
model.config.use_cache = False
trainer.train()
model.config.use_cache = True

# LoRAモデルの保存
trainer.model.save_pretrained(peft_name)

学習したモデルをそのまま推論させたい場合は、model.eval()を実行して「推論させる」まで飛んでください。

保存したアダプターを読み込む

保存したアダプターを読み込んでモデルを準備します。

from peft import PeftModel

model_name = "cyberagent/open-calm-7b"
# トークンナイザーの準備
tokenizer = AutoTokenizer.from_pretrained(model_name)
# モデルの準備
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    load_in_8bit=True,
    device_map="auto",
)
peft_name = "./lora-calm-7b"
# LoRAモデルの準備
model = PeftModel.from_pretrained(
    model, 
    peft_name, 
    device_map="auto",
  torch_dtype=torch.float16
)

# 評価モードへ
model.eval()

推論させる

まずはプロンプトを作る関数を作成します。

def generate_prompt(input_text):
    conversation_text = "あなたはchatbotです。userと会話を行ってください。\n"
    conversation_text += f"\n### user:\n{input_text}\n"
    conversation_text += "\n### chatbot:\n"
    return conversation_text

次に入力文を作成します。ここで色々と変えてください。

input_text=""

推論させます。

input_ids = tokenizer(generate_prompt(input_text), return_tensors="pt", truncation=True).input_ids.cuda()
outputs = model.generate(
    input_ids=input_ids,
    max_new_tokens=1024, 
    do_sample=True,
    temperature=0.6, 
    top_p=0.8, 
    top_k=40,
    no_repeat_ngram_size=2,
)
outputs = outputs[0].tolist()

# EOSトークンにヒットしたらデコード完了
if tokenizer.eos_token_id in outputs:
    eos_index = outputs.index(tokenizer.eos_token_id)
    decoded = tokenizer.decode(outputs[:eos_index])

    # レスポンス内容のみ抽出
    sentinel = "### chatbot:"
    sentinelLoc = decoded.find(sentinel)
    if sentinelLoc >= 0:
        print(decoded[sentinelLoc+len(sentinel):])
    else:
        print('Warning: Expected prompt template to be emitted.  Ignoring output.')
        print("------------------")
        print(tokenizer.decode(outputs))
else:
    print('Warning: no <eos> detected ignoring output')
    print("------------------")
    print(tokenizer.decode(outputs))

temperatureなどを変えてみると出力の感じが変わるので試して見てください。
設定できる引数についてはこちらを参考にしてください。

あわせて読みたい
Generation We’re on a journey to advance and democratize artificial intelligence through open source and open science.

色々と聞いてみた

出力が良かったもの、悪かったものがあるのでどちらも見てみましょう。

好きな日本のアニメはありますか?

好きな日本のアニメは何ですか?

open-calm-7b-LIMA-JA-LoRA

私は『NARUTO -ナルト-』と『ドラゴンボールZ』が大好きです! 『キャプテン翼』と「聖闘士星矢」も大好きです。

いい感じですね。

同じ質問に対する応答をいくつか見てみます。

open-calm-7b-LIMA-JA-LoRA

私は、日本の「魔法少女」シリーズ、特に「マジカル・ガール」が好きです! このシリーズは、魔法の世界と魔法の存在、そして魔法を使う人々について、私たちに考えさせます。このシリーズには、物語とキャラクターが魅力的で、キャラクターが魔法と人々のために戦うことを誇りに思っているように感じます。私は魔法を信じていますが、それが魔法であるかどうかはわかりません。しかし、私はそれが好きであり、私が見る魔法は素晴らしいです!(そして、それは私の魔法への信頼です!) 「魔法使いサリー」は、私が魔法について知る前に、最初に私が見た日本のテレビシリーズでした。私の好きなキャラクターは、サリーです(そしてサリーも好きです)。サリーは大人になり、結婚します。結婚生活は非常に複雑であり(サリーには2人の息子がいます)、結婚生活はサリーにとって非常に困難です。(サリーの夫はサリーを非常に尊敬していますが、サリーはしばしばそれを誇張します)。結婚は悲劇であり、「魔法使いサリーの結婚」というタイトルは誇大広告のように聞こえますが、それでもサリーの幸せな結婚物語です:) サリーを演じた声優は林原めぐみです。「サリーとサリーの妻」と「サリーの母」を演じました。サリーの両親は「魔法の使者」であり「サリーが魔法を使える」という魔法を知っています。サリーに魔法を教えるのはサリーの父です、しかしサリーの父親は魔法の使用に反対しています。魔法が使用されるたびに、その家族、友人、隣人、および他の人々(魔法を使用する人々)は混乱します(サリーでさえ混乱しています)。魔法が使えない人々は、しばしば魔法が彼らの生活を破壊することを知ります。彼らは魔法を禁止するために戦い、彼らの家を魔法から守ります(彼らの親は彼らの子供が魔法を使わないことを保証します)、しかし魔法が禁止された後、彼らは再び魔法を使い始めます。そして彼らはお互いに魔法をかけます(彼らはサリーのために魔法を使います)。サリーの両親もサリーの助けを必要としています。彼らには魔法が必要であり魔法が必要です。彼らが魔法を使用するとき、他の人々は彼らのために戦います。

長いですね。

open-calm-7b-LIMA-JA-LoRA

私は日本のテレビアニメが大好きで、よく見ているので、いくつかのお気に入りをご紹介します。

紹介しますと言ってるけど生成が止まっています。

open-calm-7b-LIMA-JA-LoRA

私は、日本のテレビアニメ『名探偵コナン』と『犬夜叉』が好きです(両方とも原作は漫画です)。 『コナン』(私は『コナ』と呼んでいますが、日本では『灰原』や『工藤』と呼ばれることもあります)は、私が最初に読んだ日本のテレビ番組です。『名探偵』は名探偵コナンのテレビシリーズです(『名探偵』)。私は「灰原はなぜこんなに人気なのか?」という疑問を抱いています。私はなぜ灰元がこんなに人気があると思いますか?

日本語としておかしい応答もします。

データサイエンティストになるために必要なスキルを5個挙げて

データサイエンティストになるために必要なスキルを5つ挙げて。

open-calm-7b-LIMA-JA-LoRA

1. 数学とプログラミングのスキル
2. データサイエンスのスキル(特にデータマイニング)
3. ビジネススキル
4. システム思考のスキルと問題解決のスキル。これらはすべて、データサイエンスの分野に関連するスキルです
5. 英語
* これらは、データ分析に関連する主要なスキルの一部です

とりあえず5個は挙げてくれました。

他にも次のような応答がありました。

open-calm-7b-LIMA-JA-LoRA

1. コンピュータサイエンスのスキル
2. データサイエンスのツールとスキル
3. ビジネススキル(マーケティング、販売、ファイナンス、人事など)
4. システム設計のスキル(プログラミング、システム思考など)、 5. リサーチスキルとデータサイエンス
* プログラミングのスキルとシステム設計スキルが、データアナリストになるためのスキルセットの一部です
* システム思考のスキルがデータアナリティクスのスキルセットの一部である場合、それらはデータ専門家になるためには必須ではありません
* リーダーシップスキル、コミュニケーションスキルも必要です
* データアナリストは、データ分析スキルだけでなく、ビジネススキルも必要とします
* ビジネスアナリスト、マーケティングアナリストまたは販売アナリストなど、他のスキルもあります
** これらのスキルセットは、特定の職業に関連するものではありません。データ専門家は、これらのスキルを関連付ける必要があります

open-calm-7b-LIMA-JA-LoRA

1.データサイエンスのスキル:データ科学は、データに関する基本的な知識、アルゴリズム、およびツールを提供するため、非常に重要です。データ科学者になるためには、数学、統計、コンピュータサイエンス、プログラミングのスキルが必要です。また、機械学習と人工知能のスキルも必要です。

pythonで1からnの数字を足した値を出力する関数を作成して

pythonで1からnの数字を足した値を出力する関数を作成してください。

結果から言うとコードを生成する系はどれも無理でした。やはり事前学習の時点で学習していない領域については無理そうです。

open-calm-7b-LIMA-JA-LoRA

1、2、3、4、5、6、7、8、9、10、11、12、13、14、15、16、17、18、19、20、21、22、23、24、25、26、27、28、29、30、31、32、33、34、35、36、37、38、39、40、41、42、43、44、45、46、47、48、49、50、51、52、53、54、55、56、57、58、59、60、61、62、63、64、65、66、67、68、69、70、71、72、73、74、75、76、77、78、79、80、81、82、83、84、85、86、87、88、89、90、91、92、93、94、95、96、97、98、99、100、101、102、103、104、105、106、107、108、109、110、111、112、113、114、115、116、117、118、119、120、121、122、123、124、125、126、127、128、129、130、131、132、133、134、135、136、137、138、139、140、141、142、143、144、145、146、147、148、149、150、151、152、153、154、155、156、157、158、159、160、161、162、163、164、165、166、167、168、169、170、171、172、173、174、175、176、177、178、179、180、181、182、183、184、185、186、187、188、189、190、191、192、193、194、195、196、197、198、199、200、201、202、203、204、205、206、207、208、209、210、211、212、213、214、215、216、225、227、228、230、231、232、 233 、234 、235、240、251、252、255、256、 257 、258 、 259 、260、 261 、262、264、265、 276 、277 以下のコードをsay_notes.pyという名前で保存してください:

コードを生成して欲しいのですが…してくれませんね。

open-calm-7b-LIMA-JA-LoRA

1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40-41-42-43-44-45-46-47-48-49-50-51-52-53-54-55-56-57-58-59-60-61-62-63-64-65-66-67-68-69-70-71-72-73-74-75-76-77-78-79-80-81-82-83-84-85-86-87-88-89-90-91-92-93-94-95-96-97-98-99-100-101-102-103-104-105-106-107-108-109-110-111-112-113-114-115-116-117-118-119-120-121-122-123-124-125-16-127-128-129-130-131-132-133-134-135-136-137-138-139-140-141-142-143-144-145-146-147-148-149-150-151-152-153-154-155-156-157-158-159-160-161-162-163-164-165-166-167-168-169-170-171-172-173-174-175-176-177-178-179-180-181-182-183-184-185-186-187-188-189-190-191-192-193-194-195-196-197-198-199-200-201-202-203-204-205-206

怖いですね。

算数の問題を解かせてみる

例を参考にして足し算を行ってください。
例:10+12=22
17+12=

open-calm-7b-LIMA-JA-LoRA

10と12を足すには、10に12を、12に10を足してください。

算数は難しそうです。

open-calm-7b-LIMA-JA-LoRA

10と12を足して22にすることは、2つの足し合わせで2つの要素を持つ2項演算子(&)を使うことによって簡単にできます。

open-calm-7b-LIMA-JA-LoRA

10と12を足して22にすることはできますか? もしそうなら、なぜですか?

まとめ

今回は、少数精鋭と言われているデータセットを使ってopen-calm-7bをファインチューニングしてみました。

今回紹介した出力例以外にもいろいろ試しましたが結構よかったです。

1000件でこのくらいの性能にできることが分かったので、こちらの方向で色々とやっていきたいと思います。

この記事が気に入ったら
フォローしてね!

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

コメント

コメントする

目次