本笔记本已经过测试,可以在 SageMaker Studio 中使用
SageMaker Distribution 1.3
内核运行
在本笔记本中,我们将构建用于在亚马逊 Bedrock 中持续预训练和评估基础模型(FM)的端到端工作流程。
**警告:**本笔记本将创建预置吞吐量来测试微调后的模型。因此,请确保在笔记本的最后一部分删除预置吞吐量,否则即使我们不使用它,也会被收费。
安装并导入完成本笔记本所需的所有库和依赖项。
{代码} !pip install –upgrade pip !pip install -qU –force-reinstall boto3 langchain datasets typing_extensions pypdf !pip install ipywidgets !pip install jsonlines %store -r role_arn %store -r bucket_name {代码}
检索可用于继续预训练的基础模型的 modelId。
{代码} bedrock = boto3.client(service_name="bedrock”) boto3_session = boto3.session.Session() s3_client = boto3.client(‘s3’) sts_client = boto3.client(‘sts’) account_id = sts_client.get_caller_identity()[“Account”] region_name = boto3_session.region_name s3_suffix = f”{region_name}-{account_id}”
print(“s3 bucket name: “, bucket_name)
for model in bedrock.list_foundation_models( byCustomizationType="CONTINUED_PRE_TRAINING”)[“modelSummaries”]: print("———————————–") print("{} – {}".format(model[“providerName”], model[“modelName”])) print("———————————–") for key, value in model.items(): print(key, “:", value) print("\n”) {代码}
要对文本到文本模型进行持续预训练,请通过创建一个包含多个 JSON 行的 JSONL 文件来准备训练和可选的验证数据集。由于持续预训练涉及无标签数据,每个 JSON 行都是一个只包含输入字段的样本。使用每个令牌 6 个字符作为令牌数的近似值。格式如下:
{"input": "<input text>"}
{"input": "<input text>"}
{"input": "<input text>"}
以下是可能包含在训练数据中的示例项目:
{"input": "AWS 代表亚马逊网络服务"}
有关如何准备 Bedrock 持续预训练数据集 的更多指导。
一旦我们的持续预训练数据集准备就绪,请将其上传到 Amazon S3,并保存 s3Uri 以用于创建持续预训练作业。
使用 PDF 文件创建数据集。 确保我们的数据集与模型成比例。由于基础模型的大小很大,持续预训练需要更大的数据集。如果我们使用的是一个小数据集,例如一个只有几页的 PDF 文件,我们将无法看到模型响应的显著差异。
对于本研讨会,我们使用<code>aws-cli 用户指南</code> 。
**注意:**下载数据集将需要大约 20 分钟,因为数据集包含 500 万行,大小为 22.3 GB。但是,为了训练模型,我们只会使用数据集的一个子集。
{代码} !mkdir data url = ‘https://docs.aws.amazon.com/pdfs/cli/latest/userguide/aws-cli.pdf' file_name = “./data/aws-cli.pdf” urlretrieve(url, file_name) {代码}
请注意以下持续预训练 定制作业的配额。
描述 | 最大值(持续预训练) | 可调整 |
---|---|---|
批量大小为 2 时输入和输出令牌之和 | 4,096 | 否 |
批量大小在 3 到 6 之间时输入和输出令牌之和 | 2,048 | 否 |
数据集中每个样本的字符配额 | 令牌配额 x 6 | 否 |
数据集中的训练记录 | 100,000 | 是 |
数据集中的验证记录 | 1,000 | 是 |
训练数据集文件大小 | 10 GB | 是 |
验证数据集文件大小 | 100 MB | 是 |
根据上述配额,我们首先加载 PDF 文件,根据上述配额对其进行分块,并转换为持续预训练作业所需的格式。
{"input": "<input text>"}
{代码} loader = PyPDFLoader(file_name) document = loader.load()
text_splitter = RecursiveCharacterTextSplitter( # 设置一个非常小的块大小,只是为了演示。 chunk_size = 20000, # 4096 个令牌 * 6 个字符/令牌 = 24,576 chunk_overlap = 2000, # 用于块之间连续性的重叠 )
docs = text_splitter.split_documents(document)
contents = "” for doc in docs: content = {“input”: doc.page_content} contents += (json.dumps(content) + “\n”)
dataset_folder = “data” train_file_name = “aws-cli-dataset.jsonl” train_dataset_filename = f”./{dataset_folder}/{train_file_name}”
with open(train_dataset_filename, “w”) as file: file.writelines(contents) file.close()
path = f’{dataset_folder}’ folder_name = “continued-pretraining” #我们的文件夹名称
s3_client = boto3.client(“s3”) s3_client.upload_file(f’{path}/{train_file_name}', bucket_name, f’{folder_name}/train/{train_file_name}')
s3_train_uri=f’s3://{bucket_name}/{folder_name}/train/{train_file_name}’ s3_train_uri {代码}
现在我们已经准备好数据集并将其上传,是时候启动一个新的持续预训练作业了。完成以下字段,以便调用 create_model_customization_job() API。
{代码} from datetime import datetime ts = datetime.now().strftime("%Y-%m-%d-%H-%M-%S”)
base_model_id = “amazon.titan-text-lite-v1:0:4k”
customization_type = “CONTINUED_PRE_TRAINING”
customization_role = role_arn
customization_job_name = f"cpt-titan-lite-books-{ts}”
custom_model_name = f"cpt-titan-lite-books-{ts}”
hyper_parameters = { “epochCount”: “1”, “batchSize”: “1”, “learningRate”: “0.00005”, }
training_data_config = {“s3Uri”: s3_train_uri}
'’’
validation_data_config = { “validators”: [{ # “name”: “validation”, “s3Uri”: s3_validation_uri }] } '’’
output_data_config = {“s3Uri”: “s3://{}/{}/output/".format(bucket_name, folder_name)}
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_status = bedrock.get_model_customization_job(jobIdentifier=customization_job_name)[“status”]
import time
while training_job_status == “InProgress”: time.sleep(60) fine_tune_job = bedrock.get_model_customization_job(jobIdentifier=customization_job_name)[“status”] print (training_job_status) {代码}
一旦定制作业完成,我们就可以检查现有的自定义模型,并检索我们的持续预训练模型的 modelArn。
{代码}
bedrock.list_custom_models()
custom_model_arn = bedrock.get_custom_model(modelIdentifier=custom_model_name)[‘modelArn’] custom_model_arn {代码}
配置自定义模型并将其与基础模型进行比较,以评估改进情况。
{代码} bedrock_runtime = boto3.client(service_name="bedrock-runtime”)
import boto3 boto3.client(service_name='bedrock’) provisioned_model_id = bedrock.create_provisioned_model_throughput( modelUnits=1, provisionedModelName='custom_model_name’, modelId=bedrock.get_custom_model(modelIdentifier=custom_model_name)[‘modelArn’] )[‘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)
provider = “Amazon”
for model in bedrock.list_foundation_models( byProvider=provider)[“modelSummaries”]: print("———————————–") print("{} – {}".format(model[“providerName”], model[“modelName”])) print("———————————–") for key, value in model.items(): print(key, “:", value) print("\n”)
bedrock.list_provisioned_model_throughputs()
provisioned_model_arn=bedrock.list_provisioned_model_throughputs()[“provisionedModelSummaries”][0][“provisionedModelArn”]
model_ids = [f"arn:aws:bedrock:{region_name}::foundation-model/amazon.titan-text-lite-v1”, provisioned_model_arn] #包括我们的自定义模型和基础模型进行测试
def compare_model_outputs(model_ids, prompt): for model in model_ids: response = bedrock_runtime.invoke_model( modelId=model, body = json.dumps({ “inputText”: prompt, “textGenerationConfig”: { “maxTokenCount”: 300, “stopSequences”: [], “temperature”: 0, “topP”: 0.3 } }) ) response_body = json.loads(response.get(“body”).read()) print("———————————–") print(model) print(response_body[“results”][0][“outputText”]) print("———————————–")
prompt = "”” 编写一个 aws-cli bash 脚本来创建一个 DynamoDB 表。 不要重复答案。 不要添加任何前言。 "””
compare_model_outputs(model_ids, prompt) {代码}
{代码} bedrock.delete_provisioned_model_throughput(provisionedModelId=provisioned_model_id) {代码}