初始化项目,由ModelHub XC社区提供模型
Model: stockmark/stockmark-13b Source: Original Platform
This commit is contained in:
235
notebooks/LoRA.ipynb
Normal file
235
notebooks/LoRA.ipynb
Normal file
@@ -0,0 +1,235 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1a884871-7a65-4501-9063-c85ad260d0da",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"このnotebookはstockmark/stockmark-13bのモデルをkunishou/databricks-dolly-15k-jaのデータセットを用いてLoRA tuningするためのコードの例です。A100またはH100のGPUを用いることを想定しています。\n",
|
||||
"\n",
|
||||
"- モデル:https://huggingface.co/stockmark/stockmark-13b\n",
|
||||
"- データ:https://github.com/kunishou/databricks-dolly-15k-ja\n",
|
||||
"\n",
|
||||
"以下の例では、学習を1 epochを行います。A100 GPUで実行すると30分ほどかかります。\n",
|
||||
"\n",
|
||||
"また、ここで用いられているハイパーパラメータは最適化されたものではありませんので、必要に応じて調整してください。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "93b3f4b5-2825-4ef3-a0ee-7a60155aee5d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 準備"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6a694ba9-a0fa-4f14-81cf-f35f683ba889",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import torch\n",
|
||||
"import datasets\n",
|
||||
"from transformers import AutoTokenizer, AutoModelForCausalLM, Trainer, TrainingArguments\n",
|
||||
"from peft import get_peft_model, LoraConfig, PeftModel, PeftConfig\n",
|
||||
"\n",
|
||||
"model_name = \"stockmark/stockmark-13b\"\n",
|
||||
"peft_model_name = \"stockmark-13b-adapter\"\n",
|
||||
"\n",
|
||||
"prompt_template = \"\"\"### Instruction:\n",
|
||||
"{instruction}\n",
|
||||
"\n",
|
||||
"### Input:\n",
|
||||
"{input}\n",
|
||||
"\n",
|
||||
"### Response:\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"def encode(sample):\n",
|
||||
" prompt = prompt_template.format(instruction=sample[\"instruction\"], input=sample[\"input\"])\n",
|
||||
" target = sample[\"output\"]\n",
|
||||
" input_ids_prompt, input_ids_target = tokenizer([prompt, target], add_special_tokens=False).input_ids\n",
|
||||
" input_ids_prompt = [ tokenizer.bos_token_id ] + input_ids_prompt\n",
|
||||
" input_ids_target = input_ids_target + [ tokenizer.eos_token_id ]\n",
|
||||
" input_ids = input_ids_prompt + input_ids_target\n",
|
||||
" labels = input_ids.copy()\n",
|
||||
" labels[:len(input_ids_prompt)] = [-100] * len(input_ids_prompt) # ignore label tokens in a prompt for loss calculation\n",
|
||||
" return {\"input_ids\": input_ids, \"labels\": labels}\n",
|
||||
"\n",
|
||||
"def get_collator(tokenizer, max_length):\n",
|
||||
" def collator(batch):\n",
|
||||
" batch = [{ key: value[:max_length] for key, value in sample.items() } for sample in batch ]\n",
|
||||
" batch = tokenizer.pad(batch)\n",
|
||||
" batch[\"labels\"] = [ e + [-100] * (len(batch[\"input_ids\"][0]) - len(e)) for e in batch[\"labels\"] ]\n",
|
||||
" batch = { key: torch.tensor(value) for key, value in batch.items() }\n",
|
||||
" return batch\n",
|
||||
"\n",
|
||||
" return collator"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "51e6cfcf-1ac1-400e-a4bc-ea64375d0f9e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# データセットとモデルのロード"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3ac80067-4e60-46c4-90da-05647cf96ccd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load_tokenizer\n",
|
||||
"tokenizer = AutoTokenizer.from_pretrained(model_name)\n",
|
||||
"\n",
|
||||
"# prepare dataset\n",
|
||||
"dataset_name = \"kunishou/databricks-dolly-15k-ja\"\n",
|
||||
"dataset = datasets.load_dataset(dataset_name)\n",
|
||||
"dataset = dataset.map(encode)\n",
|
||||
"dataset = dataset[\"train\"].train_test_split(0.1)\n",
|
||||
"train_dataset = dataset[\"train\"]\n",
|
||||
"val_dataset = dataset[\"test\"]\n",
|
||||
"\n",
|
||||
"# load model\n",
|
||||
"model = AutoModelForCausalLM.from_pretrained(model_name, device_map=\"auto\", torch_dtype=torch.bfloat16)\n",
|
||||
"\n",
|
||||
"peft_config = LoraConfig(\n",
|
||||
" task_type=\"CAUSAL_LM\",\n",
|
||||
" inference_mode=False,\n",
|
||||
" target_modules=[\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\"],\n",
|
||||
" r=16,\n",
|
||||
" lora_alpha=32,\n",
|
||||
" lora_dropout=0.05\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"model = get_peft_model(model, peft_config)\n",
|
||||
"model.print_trainable_parameters()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9b471da0-7fba-4127-8b07-22da4cbee6a9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LoRA Tuning"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b9bafa12-538c-4abb-b8b3-bffeb0990b46",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"training_args = TrainingArguments(\n",
|
||||
" output_dir=\"./log_stockmark_13b\",\n",
|
||||
" learning_rate=2e-4,\n",
|
||||
" per_device_train_batch_size=2,\n",
|
||||
" gradient_accumulation_steps=8,\n",
|
||||
" per_device_eval_batch_size=16,\n",
|
||||
" num_train_epochs=1,\n",
|
||||
" logging_strategy='steps',\n",
|
||||
" logging_steps=10,\n",
|
||||
" save_strategy='epoch',\n",
|
||||
" evaluation_strategy='epoch',\n",
|
||||
" load_best_model_at_end=True,\n",
|
||||
" metric_for_best_model=\"eval_loss\",\n",
|
||||
" greater_is_better=False,\n",
|
||||
" save_total_limit=2\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"trainer = Trainer(\n",
|
||||
" model=model,\n",
|
||||
" args=training_args,\n",
|
||||
" train_dataset=train_dataset,\n",
|
||||
" eval_dataset=val_dataset,\n",
|
||||
" data_collator=get_collator(tokenizer, 320)\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# LoRA tuning\n",
|
||||
"trainer.train()\n",
|
||||
"\n",
|
||||
"# save model\n",
|
||||
"model = trainer.model\n",
|
||||
"model.save_pretrained(peft_model_name)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a3f80a8e-1ac2-4bdc-8232-fe0ee18ffff5",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 学習したモデルのロード(Optional)\n",
|
||||
"異なるセッションでモデルを読み込む場合、まず最初の準備のセクションのコードを実行して、このコードを実行してください。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "43241395-3035-4cb9-8c1c-45ffe8cd48be",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"tokenizer = AutoTokenizer.from_pretrained(model_name)\n",
|
||||
"model = AutoModelForCausalLM.from_pretrained(model_name, device_map=\"auto\", torch_dtype=torch.bfloat16)\n",
|
||||
"model = PeftModel.from_pretrained(model, peft_model_name)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2ce4db1f-9bad-4c8e-9c04-d1102b299f24",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 推論"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d7d6359b-e0ac-49df-a178-39bb9f79ca93",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"prompt = prompt_template.format(instruction=\"自然言語処理とは?\", input=\"\")\n",
|
||||
"\n",
|
||||
"inputs = tokenizer(prompt, return_tensors=\"pt\").to(model.device)\n",
|
||||
"with torch.no_grad():\n",
|
||||
" tokens = model.generate(\n",
|
||||
" **inputs,\n",
|
||||
" max_new_tokens=128,\n",
|
||||
" do_sample=True,\n",
|
||||
" temperature=0.7\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"output = tokenizer.decode(tokens[0], skip_special_tokens=True)\n",
|
||||
"print(output)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
138
notebooks/inferentia2.ipynb
Normal file
138
notebooks/inferentia2.ipynb
Normal file
@@ -0,0 +1,138 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "74c647e6-d096-4e89-af82-a6ca26f80864",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# AWS Inferentia2を用いたstockmark/stockmark-13bの推論\n",
|
||||
"\n",
|
||||
"このノートブックでは、`AWS Inferentia2`上で`stockmark-13b`の推論を実行する方法について説明します。\n",
|
||||
"\n",
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"`AWS Inferentia2`を搭載した`AMAZON EC2 inf2`インスタンスを起動します。AMIは`Deep Learning AMI Neuron PyTorch 1.13`の最新版を、インスタンスタイプは`inf2.8xlarge`を選びます。より高い推論パフォーマンスを得るために、`inf2.24xlarge`や`inf2.48xlarge`などの大きなインスタンスタイプを用いることもできます。\n",
|
||||
"\n",
|
||||
"参考:[Get Started with Latest Release of PyTorch Neuron (torch-neuronx)](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/general/setup/neuron-setup/pytorch/neuronx/ubuntu/torch-neuronx-ubuntu20-pytorch-dlami.html#setup-torch-neuronx-ubuntu20-dlami-pytorch)\n",
|
||||
"\n",
|
||||
"インスタンスの起動後にインスタンスに接続し、まず仮想環境を作成します。\n",
|
||||
"\n",
|
||||
"`source /opt/aws_neuron_venv_pytorch/bin/activate`\n",
|
||||
"\n",
|
||||
"その後に、`transformers-neuronx`のライブラリをインストールします。\n",
|
||||
"\n",
|
||||
"`pip install transformers-neuronx --extra-index-url=https://pip.repos.neuron.amazonaws.com`\n",
|
||||
"\n",
|
||||
"参考:[Transformers NeuronX (transformers-neuronx)](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/libraries/transformers-neuronx/index.html)\n",
|
||||
"\n",
|
||||
"## Quickstart\n",
|
||||
"\n",
|
||||
"以下では、`AWS Inferentia2`上で`stockmark-13b`の推論(テキスト生成)を行うコードを紹介します。このノートブックは以下のチュートリアルをもとに作成しました。詳しくはこちらもご覧ください。\n",
|
||||
"\n",
|
||||
"参考:[Run Hugging Face meta-llama/Llama-2-13b autoregressive sampling on Inf2 & Trn1](https://github.com/aws-neuron/aws-neuron-samples/blob/master/torch-neuronx/transformers-neuronx/inference/meta-llama-2-13b-sampling.ipynb)\n",
|
||||
"\n",
|
||||
"`transformers-neuronx`を用いて推論を行うためには、事前にモデルファイルをライブラリに対応した形式に変換しておく必要があります。以下のコードは、`stockmark-13b`のモデルをHuggingface Hubからダウンロードし、`./stockmark-13b-split`というディレクトリに保存します。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0475c514-6eb6-4457-aa34-62e1d42517a2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import torch\n",
|
||||
"from transformers_neuronx.module import save_pretrained_split\n",
|
||||
"from transformers import LlamaForCausalLM\n",
|
||||
"\n",
|
||||
"model = LlamaForCausalLM.from_pretrained('stockmark/stockmark-13b', torch_dtype=torch.bfloat16)\n",
|
||||
"save_pretrained_split(model, './stockmark-13b-split')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2a85d74d-757e-4d4c-b81a-9a5b5286207a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"コードが終了したらJupyterLabのカーネルを再起動してください。\n",
|
||||
"\n",
|
||||
"次のコードで、`stockmark-13b`の推論を実行することができます。\n",
|
||||
"\n",
|
||||
"PyTorchでの推論と異なり、AWS Inferentia2で推論を行うために、計算グラフをコンパイルする必要があり、それに数分程度の時間がかかります。次回以降は、キャッシュされた結果が用いられます。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ef9a9a2d-43a7-4611-8708-e2dea60454c5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"import torch\n",
|
||||
"from transformers import AutoTokenizer\n",
|
||||
"from transformers_neuronx.llama.model import LlamaForSampling\n",
|
||||
"\n",
|
||||
"os.environ['NEURON_CC_FLAGS'] = '-O1'\n",
|
||||
"\n",
|
||||
"## load tokenizer\n",
|
||||
"tokenizer = AutoTokenizer.from_pretrained('stockmark/stockmark-13b')\n",
|
||||
"\n",
|
||||
"## load model\n",
|
||||
"model = LlamaForSampling.from_pretrained(\"./stockmark-13b-split\", batch_size=1, tp_degree=2, amp='f16')\n",
|
||||
"model.to_neuron() # compile\n",
|
||||
"\n",
|
||||
"## inference\n",
|
||||
"prompt = \"自然言語処理とは?\"\n",
|
||||
"inputs = tokenizer(prompt, return_tensors=\"pt\")\n",
|
||||
"\n",
|
||||
"with torch.inference_mode():\n",
|
||||
" tokens = model.sample(inputs.input_ids, temperature = 1.0, sequence_length = 256)\n",
|
||||
" \n",
|
||||
"generated_text = tokenizer.decode(tokens[0], skip_special_tokens=True)\n",
|
||||
"\n",
|
||||
"print(generated_text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e19998fa-2db4-4bf2-b914-10d0885f5388",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Tensor parallelism\n",
|
||||
"\n",
|
||||
"`transformers-neuronx`のライブラリではテンソル並列化をサポートされています。これにより、モデルを複数のNeuronCoreに配置し、計算を並列に行うことで、推論のパフォーマンスを高めることができます。並列数(いくつのNeuronCoreを用いるか)は、モデルのロードを行う関数`LlamaForSampling.from_pretrained`の引数`tp_degree`から指定することができます。上の例では、`tp_degree=2`を指定しています。\n",
|
||||
"\n",
|
||||
"指定可能な`tp_degree`の値は、インスタンスタイプに依存します。大きなインスタンスを用いて、`tp_degree`の値を大きくすることで、latencyを小さくすることができます。\n",
|
||||
"\n",
|
||||
"| インスタンスタイプ | 指定可能なtp_degreeの最大数 |\n",
|
||||
"|:---:|:---:|\n",
|
||||
"|inf2.8xlarge|2|\n",
|
||||
"|inf2.24xlarge|12|\n",
|
||||
"|inf2.48xlarge|24|"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Reference in New Issue
Block a user