使用Amazon SageMaker探索医疗摘要选项

探索医疗摘要选项' (Explore medical summary options)

在当今快速发展的医疗保健领域中,医生面临来自各种来源的大量临床数据,如医护人员的笔记、电子健康记录和影像报告。这些丰富的信息对患者护理至关重要,但对医疗专业人员来说也可能是压倒性和耗时的。高效地总结和提取这些数据的见解对于更好的患者护理和决策至关重要。总结的患者信息对于诸如数据聚合、有效编码患者或对具有相似诊断的患者进行审核等下游流程非常有用。

人工智能(AI)和机器学习(ML)模型在解决这些挑战方面显示出巨大的潜力。模型可以训练用于分析和解释大量文本数据,有效地将信息压缩成简洁的摘要。通过自动化摘要过程,医生可以快速获取相关信息,从而专注于患者护理并做出更明智的决策。请查看以下案例研究,了解更多真实世界的应用案例。

Amazon SageMaker是一个完全托管的ML服务,为托管和实施各种基于AI/ML的摘要模型和方法提供了理想的平台。在本文中,我们将探讨在SageMaker上实现摘要技术的不同选项,包括使用Amazon SageMaker JumpStart基础模型、微调Hugging Face的预训练模型以及构建自定义摘要模型。我们还讨论了每种方法的优缺点,使医疗专业人员能够选择最适合生成复杂临床数据简明准确摘要的解决方案。

在我们开始之前,有两个重要的术语需要了解:预训练和微调。预训练或基础模型是在大量数据语料库上构建和训练的模型,通常用于一般语言知识。微调是在预训练模型上给定另一个更具领域特定数据集的过程,以增强其在特定任务上的性能。在医疗保健环境中,这意味着向模型提供一些与患者护理特定短语和术语相关的数据。

在SageMaker上构建自定义摘要模型

尽管是最费力的方法,但有些组织可能更喜欢从头开始在SageMaker上构建自定义摘要模型。这种方法需要更深入的AI/ML模型知识,可能涉及从头创建模型架构或调整现有模型以适应特定需求。构建自定义模型可以提供更大的灵活性和对摘要过程的控制,但与从预训练模型开始的方法相比,也需要更多的时间和资源。在继续之前,权衡此选项的利弊是至关重要的,因为它可能不适用于所有用例。

SageMaker JumpStart基础模型

在SageMaker上实现摘要的一种很好的选择是使用JumpStart基础模型。这些模型由领先的AI研究机构开发,为各种任务提供了一系列经过优化的预训练语言模型,包括文本摘要。SageMaker JumpStart提供两种类型的基础模型:专有模型和开源模型。SageMaker JumpStart还提供HIPAA合规性,使其非常适用于医疗工作负载。最终由客户保证合规性,因此请务必采取适当步骤。有关更多细节,请参阅AWS上的HIPAA安全和合规性架构。

专有基础模型

专有模型,如AI21的Jurassic模型和Cohere的Generate模型,可以通过SageMaker JumpStart在AWS管理控制台中发现,并且目前仍处于预览阶段。当您不需要在自定义数据上微调模型时,利用专有模型进行摘要是理想的选择。这提供了一种易于使用的即插即用解决方案,可以满足您的摘要需求,并减少了对训练和微调自定义模型所需的时间和资源。此外,专有模型通常配有用户友好的API和SDK,简化与现有系统和应用程序的集成过程。如果您的摘要需求可以通过预训练的专有模型来满足,而无需特定定制或微调,则它们为文本摘要任务提供了一种便捷、经济高效的解决方案。因为这些模型并非专门针对医疗用例进行训练,所以没有经过微调的情况下不能保证在医学语言方面的质量。

Jurassic-2 Grande Instruct是AI21 Labs的大型语言模型(LLM),优化用于自然语言指令并适用于各种语言任务。它提供了易于使用的API和Python SDK,平衡了质量和价格。常见用途包括生成营销文案、驱动聊天机器人和文本摘要。

在SageMaker控制台上,导航到SageMaker JumpStart,找到AI21 Jurassic-2 Grande Instruct模型,并选择试用模型

如果您想将模型部署到您管理的SageMaker终端节点,您可以按照这个示例笔记本的步骤进行操作,该示例演示了如何使用SageMaker部署Jurassic-2 Large。

开源基础模型

开源模型包括FLAN T5、Bloom和GPT-2模型,可以通过Amazon SageMaker Studio UI、SageMaker控制台上的SageMaker JumpStart以及SageMaker JumpStart APIs发现。这些模型可以通过您的AWS帐户进行微调和部署到终端节点,使您完全拥有模型权重和脚本代码的所有权。

Flan-T5 XL是一个功能强大且多功能的模型,专为各种语言任务设计。通过使用特定于域的数据对模型进行微调,您可以优化其在特定用例(如文本摘要或任何其他自然语言处理任务)中的性能。有关如何使用SageMaker Studio UI对Flan-T5 XL进行微调的详细信息,请参阅使用Amazon SageMaker Jumpstart进行FLAN T5 XL指导微调。

使用Hugging Face在SageMaker上微调预训练模型

在SageMaker上实现摘要的最受欢迎的选项之一是使用Hugging Face Transformers库对预训练模型进行微调。Hugging Face提供了一系列专为各种自然语言处理(NLP)任务(包括文本摘要)设计的预训练Transformer模型。使用Hugging Face Transformers库,您可以轻松地使用SageMaker对这些预训练模型进行微调以适应您的特定领域数据。这种方法具有许多优点,例如更快的训练时间、在特定领域上的更好性能以及使用内置的SageMaker工具和服务进行更容易的模型打包和部署。如果在SageMaker JumpStart中找不到合适的模型,您可以选择Hugging Face提供的任何模型,并使用SageMaker进行微调。

要开始使用模型学习ML的能力,您只需要打开SageMaker Studio,在Hugging Face模型中心找到您想要使用的预训练模型,并选择SageMaker作为部署方法。Hugging Face将为您提供要在笔记本中复制、粘贴和运行的代码。就是这么简单!无需ML工程经验。

Hugging Face Transformers库使构建者能够操作预训练模型并执行高级任务,如微调,我们将在以下部分中探讨这些任务。

配置资源

在开始之前,我们需要配置一个笔记本。有关说明,请参阅在本地构建和训练机器学习模型的步骤1和步骤2。对于此示例,我们使用了以下截图中显示的设置。

我们还需要创建一个Amazon Simple Storage Service(Amazon S3)存储桶,用于存储训练数据和训练成果。有关说明,请参阅创建存储桶。

准备数据集

为了使我们的模型具有更好的领域知识进行微调,我们需要获取适合任务的数据。在为企业用例进行培训时,您需要进行一些数据工程任务,以准备您自己的数据以进行培训。这些任务超出了本文的范围。对于此示例,我们生成了一些合成数据来模拟护理记录,并将其存储在Amazon S3中。将数据存储在Amazon S3中使我们能够为HIPAA合规性架构化我们的工作负载。我们首先获取这些记录,并将其加载到我们笔记本所在的实例上:

from datasets import load_dataset
dataset = load_dataset("csv", data_files={
    "train": "s3://" + bucket_name + train_data_path,
    "validation": "s3://" + bucket_name + test_data_path
})

备注是由包含完整条目的列,即note,以及包含缩写版本的列,即summary,组成的。使用这个数据集的目的是改进我们模型的生物学和医学词汇,使其更适应在医疗保健领域中进行总结,即领域微调,并向我们的模型展示如何构造其总结输出。在某些总结情况下,我们可能希望从文章中创建一个摘要或评论的一句话简介,但在这种情况下,我们尝试让我们的模型输出患者症状和迄今为止采取的措施的缩写版本。

加载模型

我们用作基础的模型是谷歌的Pegasus的一个版本,可在Hugging Face Hub上获得,称为pegasus-xsum。它已经预训练用于总结,因此我们的微调过程可以专注于扩展其领域知识。修改模型运行的任务是一种不在本文中介绍的不同类型的微调。Transformer库为我们提供了一个类,用于从我们的model_checkpoint: google/pegasus-xsum中加载模型定义。这将从hub中加载模型,并在我们的笔记本中实例化它,以便我们以后可以使用它。由于pegasus-xsum是一个序列到序列模型,我们希望使用AutoModel类的Seq2Seq类型:

from transformers import AutoModelForSeq2SeqLM
model = AutoModelForSeq2SeqLM.from_pretrained(model_checkpoint)

现在我们有了模型,现在是时候将我们的注意力转向其他组件,这些组件将使我们能够运行训练循环。

创建一个分词器

这些组件中的第一个是分词器。分词是将输入数据中的单词转换为我们的模型可以理解的数字表示的过程。同样,Transformer库为我们提供了一个类,用于从与我们用于实例化模型的相同检查点加载分词器定义:

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)

使用这个分词器对象,我们可以创建一个预处理函数,并将其映射到我们的数据集上,以获得准备好被馈送到模型中的标记。最后,我们格式化标记化的输出并删除包含原始文本的列,因为模型将无法解释它们。现在我们只剩下一个标记化的输入,准备被馈送到模型中。请参阅以下代码:

tokenized_datasets = dataset.map(preprocess_function, batched=True)

tokenized_datasets.set_format("torch")

tokenized_datasets = tokenized_datasets.remove_columns(
    dataset["train"].column_names
)

创建数据整合器和优化器

当我们的数据被标记化并且我们的模型被实例化后,我们几乎可以开始运行训练循环了。我们要创建的下一个组件是数据整合器和优化器。数据整合器是Hugging Face通过Transformer库提供的另一个类,我们使用它来为训练创建批次的标记化数据。我们可以使用我们已经拥有的分词器和模型对象轻松构建它,只需找到之前用于模型(Seq2Seq)的相应类类型(collator类)。优化器的功能是维护训练状态并根据我们的训练损失更新参数,以便我们通过循环进行工作。要创建一个优化器,我们可以从torch模块中导入optim包,其中提供了许多优化算法。您可能之前遇到过的一些常见算法是随机梯度下降和Adam,后者应用在我们的示例中。Adam的构造函数接受模型参数和给定训练运行的参数化学习率。请参阅以下代码:

from transformers import DataCollatorForSeq2Seq
from torch.optim import Adam

data_collator = DataCollatorForSeq2Seq(tokenizer, model=model)
optimizer = Adam(model.parameters(), lr=learning_rate)

构建加速器和学习率调度器

在开始训练之前的最后几个步骤是构建加速器和学习率调度器。加速器来自一个不同的库(我们主要使用Transformers库)由Hugging Face生产,名为Accelerate,它将在训练期间抽象出设备管理所需的逻辑(例如,使用多个GPU)。对于最后一个组件,我们再次使用Transformer库来实现我们的学习率调度器。通过指定调度器类型、循环中的总训练步数和先前创建的优化器,get_scheduler函数将返回一个对象,使我们能够在训练过程中调整初始学习率:

from accelerate import Accelerator
from transformers import get_scheduler

accelerator = Accelerator()
model, optimizer = accelerator.prepare(
    model, optimizer
)

lr_scheduler = get_scheduler(
    "linear",
    optimizer=optimizer,
    num_warmup_steps=0,
    num_training_steps=num_training_steps,
)

配置训练任务

现在我们已经完全准备好进行训练了!让我们设置一个训练任务,首先使用Transformers库实例化training_args并选择参数值。我们可以将这些参数和其他准备好的组件和数据集直接传递给trainer并开始训练,如下所示的代码所示。根据数据集的大小和选择的参数,这可能需要相当长的时间。

from transformers import Seq2SeqTrainer
from transformers import Seq2SeqTrainingArguments

training_args = Seq2SeqTrainingArguments(
    output_dir="output/",
    save_total_limit=1,
    num_train_epochs=num_train_epochs,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size=batch_size,
    evaluation_strategy="epoch",
    logging_dir="output/",
    load_best_model_at_end=True,
    disable_tqdm=True,
    logging_first_step=True,
    logging_steps=1,
    save_strategy="epoch",
    predict_with_generate=True
)

trainer = Seq2SeqTrainer(
    model=model,
    tokenizer=tokenizer,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    data_collator=data_collator,
    optimizers=(optimizer, lr_scheduler)
)
    
trainer.train()

为了实现此代码,我们可以将其打包为一个入口文件,并通过SageMaker训练任务调用它。这样我们可以将刚刚构建的逻辑与训练调用分离开来,并允许SageMaker在单独的实例上运行训练。

为推理打包模型

运行训练后,模型对象已经准备好供推理使用。作为最佳实践,让我们保存我们的工作以供将来使用。我们需要创建模型文件,将它们打包在一起,然后将我们的tarball上传到Amazon S3进行存储。为了准备我们的模型进行打包,我们需要解开现在微调后的模型,保存模型二进制文件和相关的配置文件。我们还需要将我们的tokenizer保存到与模型文件保存在同一目录中,这样在使用模型进行推理时它会可用。我们的model_dir文件夹现在应该看起来像以下代码:

config.json      pytorch_model.bin   tokenizer_config.json
generation_config.json  special_tokens_map.json     tokenizer.json

剩下的就是运行tar命令来压缩我们的目录,并将tar.gz文件上传到Amazon S3:

unwrapped_model = accelerator.unwrap_model(trainer.model)

unwrapped_model.save_pretrained('model_dir', save_function=accelerator.save)

tokenizer.save_pretrained('model_dir')

!cd model_dir/ && tar -czvf model.tar.gz *
!mv model_dir/model.tar.gz ./

with open("model.tar.gz", "rb") as f:
    s3.upload_fileobj(f, bucket_name, artifact_path + "model/model.tar.gz")

我们新微调的模型现在已经准备好并可以用于推理。

进行推理

要使用这个模型文件进行推理,打开一个新文件并使用以下代码,修改model_data参数以适应您在Amazon S3中的模型保存位置。HuggingFaceModel构造函数将从我们保存到model.tar.gz的检查点重新构建我们的模型,然后我们可以使用deploy方法部署进行推理。部署端点将需要几分钟的时间。

from sagemaker.huggingface import HuggingFaceModel
from sagemaker import get_execution_role

role = get_execution_role()

huggingface_model = HuggingFaceModel(
   model_data="s3://{bucket_name}/{artifact_path}/model/model.tar.gz",
   role=role,
   transformers_version="4.26",
   pytorch_version="1.13",
   py_version="py39"
)

predictor = huggingface_model.deploy(
   initial_instance_count=1,
   instance_type="ml.m5.xlarge"
)

部署端点后,我们可以使用我们创建的predictor进行测试。将数据载荷传递给predict方法并运行单元格,您将获得来自您微调模型的响应:

data = {
    "inputs": "文本摘要的内容"
}
predictor.predict(data)

结果

为了看到微调模型的好处,我们来做一个快速测试。下表包括一个提示和将该提示传递给模型进行微调前后的结果。

提示 未进行微调的响应 进行微调的响应
总结患者正在经历的症状。患者是一名45岁的男性,主诉胸骨下疼痛放射至左臂。疼痛在他做园艺工作时突然发生,伴有轻度呼吸困难和出汗。患者到达时心率为120,呼吸频率为24,血压为170/95。急诊科到达时进行了12导联心电图检查,并给予了三次舌下含服硝酸甘油,但未能缓解胸痛。心电图显示前壁导联ST段抬高,表现为急性前壁心肌梗死。我们已与心脏导管介入室联系,并准备进行心脏导管介入治疗。 我们介绍了一例急性心肌梗死的病例。 胸痛、前壁心肌梗死、冠状动脉介入治疗。

正如您所看到的,我们经过微调的模型以不同的健康术语使用,我们已能够改变响应的结构以适应我们的目的。请注意,结果取决于您的数据集和训练期间所做的设计选择。您的模型版本可能提供非常不同的结果。

清理

当您完成 SageMaker 笔记本的使用后,请务必关闭它,以避免长时间运行资源的费用。请注意,关闭实例会导致您丢失存储在实例临时内存中的任何数据,因此在清理之前应将所有工作保存到持久存储中。您还需要转到 SageMaker 控制台的“终端节点”页面,删除为推断部署的任何终端节点。为了删除所有工件,您还需要转到 Amazon S3 控制台,删除上传到您的存储桶中的文件。

结论

在本文中,我们探讨了在 SageMaker 上实现文本摘要技术的各种选项,以帮助医疗专业人员高效处理和提取大量临床数据的见解。我们讨论了使用 SageMaker Jumpstart 基础模型、微调 Hugging Face 预训练模型以及构建自定义摘要模型的方法。每种方法都有其优点和缺点,以满足不同的需求和要求。

在 SageMaker 上构建自定义摘要模型可以提供很大的灵活性和控制力,但比使用预训练模型需要更多的时间和资源。SageMaker Jumpstart 基础模型为那些不需要特定定制或微调的组织提供了易于使用且经济实惠的解决方案,以及一些简化的微调选项。微调 Hugging Face 预训练模型提供更快的训练时间、更好的领域特定性能,以及与 SageMaker 工具和服务的无缝集成,涵盖了广泛的模型目录,但需要一些实施工作。撰写本文时,亚马逊已宣布另一种选择,即 Amazon Bedrock,它将在更加托管的环境中提供摘要功能。

通过了解每种方法的优缺点,医疗专业人员和组织可以对生成复杂临床数据的简洁准确摘要的最合适解决方案做出明智的决策。最终,在 SageMaker 上使用基于 AI/ML 的摘要模型可以显著提升患者护理和决策,使医疗专业人员能够快速获取相关信息并专注于提供优质护理。

资源

有关本文中讨论的完整脚本和一些示例数据,请参阅 GitHub 存储库。有关如何在 AWS 上运行 ML 工作负载的更多信息,请参阅以下资源:

  • Hugging Face 在 Amazon SageMaker 上的研讨会
  • Hugging Face Transformers Amazon SageMaker 示例
  • Technology Innovation Institute 在 Amazon SageMaker 上训练最先进的 Falcon LLM 40B 基础模型
  • 在 Amazon SageMaker 上训练大型语言模型:最佳实践
  • Forethought 如何使用 Amazon SageMaker 为生成式 AI 模型节省超过 66% 的成本