这个笔记本应该可以很好地与 SageMaker Studio 中的
Data Science 3.0
内核一起使用。也使用 ml.c5.2xlarge 由于所需的内存资源
在这个笔记本中,我们将微调由亚马逊 Bedrock 提供的 Amazon Titan Text Lite 模型用于摘要用例。 我们可以从基础模型列表中选择,或微调我们之前微调过的模型之一。
00_setup.ipynb
笔记本。00_setup.ipynb
笔记本相同的内核和实例。警告: 这个笔记本将创建预置吞吐量来测试微调的模型。因此,请确保在笔记本的最后一节中删除预置吞吐量,否则我们将被收取费用,即使我们没有使用它。
!pip install -qU bert_score
# 重启内核以使软件包生效
from IPython.core.display import HTML
HTML("<script>Jupyter.notebook.kernel.restart()</script>")
## 从 `00_setup.ipynb` 笔记本中获取变量。
%store -r role_arn
%store -r s3_train_uri
%store -r s3_validation_uri
%store -r s3_test_uri
%store -r bucket_name
import pprint
pprint.pp(role_arn)
pprint.pp(s3_train_uri)
pprint.pp(s3_validation_uri)
pprint.pp(s3_test_uri)
pprint.pp(bucket_name)
import warnings
warnings.filterwarnings('ignore')
import json
import os
import sys
import boto3
import time
session = boto3.session.Session()
region = session.region_name
sts_client = boto3.client('sts')
s3_client = boto3.client('s3')
aws_account_id = sts_client.get_caller_identity()["Account"]
bedrock = boto3.client(service_name="bedrock")
bedrock_runtime = boto3.client(service_name="bedrock-runtime")
test_file_name = "test-cnn-10.jsonl"
data_folder = "fine-tuning-datasets"
我们需要提供要微调的模型的 base_model_id
。我们可以使用 list_foundation_models
API 获取它,如下所示:
for model in bedrock.list_foundation_models(
byCustomizationType="FINE_TUNING")["modelSummaries"]:
for key, value in model.items():
print(key, ":", value)
print("-----\n")
base_model_id = "amazon.titan-text-lite-v1:0:4k"
接下来,我们需要提供 customization_job_name
、custom_model_name
和 customization_role
,这些将用于创建微调作业。
from datetime import datetime
ts = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
customization_job_name = f"model-finetune-job-{ts}"
custom_model_name = f"finetuned-model-{ts}"
customization_role = role_arn
注意: 微调作业将需要大约 1 小时才能完成。
Amazon Titan 文本模型自定义超参数:
epochs
: 通过整个训练数据集的迭代次数,可以取 1-10 之间的任何整数值,默认值为 5。batchSize
: 在更新模型参数之前处理的样本数,可以取 1-64 之间的任何整数值,默认值为 1。learningRate
: 更新模型参数的速率,可以取 0.0-1.0 之间的浮点值,默认值设置为 1.00E-5。learningRateWarmupSteps
: 学习率逐步增加到指定速率的迭代次数,可以取 0-250 之间的任何整数值,默认值为 5。有关设置超参数的指南,请参考此处 提供的指南。
# 从"FINE_TUNING"或"CONTINUED_PRE_TRAINING"中选择自定义类型。
customization_type = "FINE_TUNING"
# 定义微调 Titan 文本模型的超参数
hyper_parameters = {
"epochCount": "2",
"batchSize": "1",
"learningRate": "0.00003",
}
s3_bucket_config=f's3://{bucket_name}/outputs/output-{custom_model_name}'
# 指定训练、验证(可选)和输出的数据路径
training_data_config = {"s3Uri": s3_train_uri}
validation_data_config = {
"validators": [{
# "name": "validation",
"s3Uri": s3_validation_uri
}]
}
output_data_config = {"s3Uri": s3_bucket_config}
# 创建自定义作业
training_job_response = bedrock.create_model_customization_job(
customizationType=customization_type,
jobName=customization_job_name,
customModelName=custom_model_name,
roleArn=customization_role,
baseModelIdentifier=base_model_id,
hyperParameters=hyper_parameters,
trainingDataConfig=training_data_config,
validationDataConfig=validation_data_config,
outputDataConfig=output_data_config
)
training_job_response
fine_tune_job = bedrock.get_model_customization_job(jobIdentifier=customization_job_name)["status"]
print(fine_tune_job)
while fine_tune_job == "InProgress":
time.sleep(60)
fine_tune_job = bedrock.get_model_customization_job(jobIdentifier=customization_job_name)["status"]
print (fine_tune_job)
time.sleep(60)
fine_tune_job = bedrock.get_model_customization_job(jobIdentifier=customization_job_name)
pprint.pp(fine_tune_job)
output_job_name = "model-customization-job-"+fine_tune_job['jobArn'].split('/')[-1]
output_job_name
现在我们准备好创建<code>预置吞吐量</code> ,这是在我们可以对微调模型进行推理之前需要的。
我们在模型单元(MU)中指定预置吞吐量。一个模型单元提供特定的吞吐量级别for指定的模型。给定文本模型的 MU 的吞吐量级别指定了以下内容:
每分钟的总输入令牌数 - 一个 MU 在一分钟内可以处理的所有请求的输入令牌数。
每分钟的总输出令牌数 - 一个 MU 在一分钟内可以生成的所有请求的输出令牌数。
模型单元配额取决于我们为预置吞吐量指定的承诺级别。
对于没有承诺的自定义模型,每个预置吞吐量可用一个模型单元的配额。我们可以为每个帐户创建最多两个预置吞吐量。
对于有承诺的基础或自定义模型,默认配额为 0 个模型单元。要请求增加,请使用限制增加表单 。
一旦自定义作业完成,我们就可以检查现有的自定义模型,并检索我们的微调模型的 modelArn。
# 列出我们的自定义模型
bedrock.list_custom_models()
model_id = bedrock.get_custom_model(modelIdentifier=custom_model_name)['modelArn']
model_id
注意: 创建预置吞吐量将需要大约 20-30 分钟才能完成。
我们需要创建预置吞吐量才能评估模型性能。我们可以通过[控制台].(https://docs.aws.amazon.com/bedrock/latest/userguide/prov-cap-console.html)或使用以下 API 调用来执行此操作:
import boto3
boto3.client(service_name='bedrock')
provisioned_model_id = bedrock.create_provisioned_model_throughput(
modelUnits=1,
provisionedModelName='test-model',
modelId=model_id
)['provisionedModelArn']
status_provisioning = bedrock.get_provisioned_model_throughput(provisionedModelId = provisioned_model_id)['status']
import time
while status_provisioning == 'Creating':
time.sleep(60)
status_provisioning = bedrock.get_provisioned_model_throughput(provisionedModelId=provisioned_model_id)['status']
print(status_provisioning)
time.sleep(60)
在调用之前,让我们从我们的测试数据中获取样本提示。
# 提供提示文本
test_file_path = f'{data_folder}/{test_file_name}'
with open(test_file_path) as f:
lines = f.read().splitlines()
test_prompt = json.loads(lines[3])['prompt']
reference_summary = json.loads(lines[3])['completion']
pprint.pp(test_prompt)
print(reference_summary)
prompt = f"""
{test_prompt}
"""
base_model_arn = f'arn:aws:bedrock:{region}::foundation-model/amazon.titan-text-lite-v1'
请确保按照此处 的说明构建模型输入,遵循 titan 文本模型所需的格式。 请注意"模型调用请求正文字段"部分中的 “body” 变量,我们将其作为有效负载传递给上面训练的自定义模型。
body = json.dumps(
{
"inputText": prompt,
"textGenerationConfig": {
"maxTokenCount": 2048,
"stopSequences": ['User:'],
"temperature": 0,
"topP": 0.9
}
}
)
accept = 'application/json'
contentType = 'application/json'
fine_tuned_response = bedrock_runtime.invoke_model(body=body,
modelId=provisioned_model_id,
accept=accept,
contentType=contentType)
base_model_response = bedrock_runtime.invoke_model(body=body,
modelId=base_model_arn,
accept=accept,
contentType=contentType)
fine_tuned_response_body = json.loads(fine_tuned_response.get('body').read())
base_model_response_body = json.loads(base_model_response.get('body').read())
print("Base model response: ", base_model_response_body["results"][0]["outputText"] + '\n')
print("Fine tuned model response:", fine_tuned_response_body["results"][0]["outputText"]+'\n')
print("Reference summary from test data: " , reference_summary)
在这一部分,我们将使用 BertScore
指标来评估微调模型与基础模型的性能,以检查微调是否提高了结果。
BERTScore
: 根据 BERT (Bidirectional Encoder Representations from Transformers) 这个强大的语言模型的输出,计算摘要和参考文本之间的相似性。Medium 文章链接
base_model_generated_response = [base_model_response_body["results"][0]["outputText"]]
fine_tuned_generated_response = [fine_tuned_response_body["results"][0]["outputText"]]
from bert_score import score
reference_summary = [reference_summary]
fine_tuned_model_P, fine_tuned_R, fine_tuned_F1 = score(fine_tuned_generated_response, reference_summary, lang="en")
base_model_P, base_model_R, base_model_F1 = score(base_model_generated_response, reference_summary, lang="en")
print("F1 score: base model ", base_model_F1)
print("F1 score: fine-tuned model", fine_tuned_F1)
从上面的分数和查看基础模型摘要、微调模型摘要和参考摘要来看,很明显微调模型会提高在其训练任务上的结果。我们只使用了 1K 条记录进行训练,100 条验证记录和 2 个 epoch,就能获得更好的结果。 我们可能需要先调整 learning_rate,可视化训练和验证指标以了解训练作业的性能,然后再增加数据的大小。
提示: 请参考提供的指南根据我们的任