亚马逊AWS官方博客

基于亚马逊云科技 AI 服务打造多模态智能化内容审核

前言

近年来,世界各地逐步加强了对各行业内容安全合规的监管力度,并推出了相关的监管政策和法规要求,旨在抑制违法、违规、暴力、色情、垃圾、酒精、毒品、隐私敏感等内容的传播和扩散,不符合安全合规要求的内容,极有可能面临企业业务产品的下架和监管部门的处罚。由此可看出,面向用户的应用和平台构建安全合规审查的重要性。然而,随着生成式人工智能(Generative AI,GenAI)技术的兴起,各类基于 GenAI 的应用和服务层出不穷,覆盖电商、娱乐媒体、零售、金融、医疗等广泛行业。GenAI 改变了传统人工生产内容的方式,大模型可以根据提示实现文本、图像、音频和视频等内容的生成。相比传统决策式 AI,GenAI 具有创新性、高效性和个性化等特点,但是现阶段也存在生成内容可控性的问题。GenAI 生成的内容可能包含误导信息、有害内容等,需要建立内容审核机制进行管控。与此同时,面向用户的 GenAI 服务也会涉及大量用户上传内容,这些 UGC 同样需要审核,过滤掉违规违法信息。内容审核涉及文本、图像、视频等多模态数据,还需要结合行业规范、法律法规等方面进行综合判断。GenAI 时代下,利用 GenAI 的内容审核技术和服务都将是非常值得关注的点。

本文将探讨如何使用亚马逊云科技提供的一系列托管人工智能服务 Amazon Rekognition ,Amazon ComprehendAmazon TranscribeAmazon Translate 和 Amazon Bedrock 以及其他技术,打造自动化的智能化内容审核系统包括图像、视频、文本和音频审核工作流程,及时过滤不合适的内容,给用户带来更好的体验。

支撑内容审核的亚马逊云科技 AI/ML 相关服务

亚马逊云科技提供了多种托管的 AI/ML 服务来检测文本、语音、图像中潜在的风险内容,为快速搭建 GenAI 内容审核系统提供了有力支持,基于这些服务可以快速构建一个适合自身业务场景的内容审核工作流,实现内容审核的自动化,保障 GenAI 应用的安全。

图像和视频审核

Amazon Rekognition 提供多种图像识别和视频分析相关的计算机视觉 API,如目标检测、面部分析、名人识别等。Rekognition 上的内容审核功能支持检测图像和视频中潜在的不安全、不适宜或有害内容,类别包括:明显裸露、暗示性、暴力、酒精、赌博等顶级类别,每个顶级分类下还有更细分的二级标签,具体类别相见文档。Rekognition 会在返回中提供标签置信度,让用户能够根据自身需求更精细地控制允许显示的图像。

最近 Rekognition 推出一项新的自定义内容审核功能,通过适配器添加到现有 Rekognition 深度学习模型中,改善在特定用例和场景下相关内容审核任务的准确性。使用 Rekognition 控制台创建、训练、评估、使用和管理适配器具体步骤参考文档

另外,部分应用可能需要从其他角度做更高要求的内容审核。例如,一些社交属性的应用可能要求设置儿童使用限制,这时可以使用 Rekognition 上的人脸检测和分析 API,识别出图像中人脸的年龄范围,来帮助应用实现年龄限制;在某些地区可能会要求平台应用禁止出现特定公众人物的面孔,Rekognition 提供名人识别 API 并且支持自定义人脸集合,可以将输入面孔与存储的人脸集合进行匹配,从而帮助应用实现对特定面孔的识别和限制。总体而言,Rekognition 人脸识别和分析相关功能可以辅助构建适用于不同应用场景和需求的智能内容审核系统,实现更丰富、更精细的审核策略来保障应用的安全合规。

文本审核

Amazon Comprehend 是一项基于自然语言处理(NLP)的文本分析服务,提供包括情感分析、实体识别、从文本中提取关键短语、主题等在内的多种自然语言处理功能。Comprehend 新推出一项毒性内容检测功能, 可以识别文本中的危险语言、威胁、骚扰语等不当内容,增强内容审核系统的精细化识别能力。在生成式 AI 应用中可以用毒性内容检测来检查输入的提示词和大语言模型输出的响应,还可以用于检测用户评论等 UGC 文本内容。另外可以调用 Comprehend 的文本分析 API,识别文本中的个人身份信息(PII),来保护和控制用户的隐私敏感数据。

Amazon Bedrock 是一项完全托管的服务,使用单个 API 提供来自 AI21 Labs、Anthropic、Cohere、Meta、Stability AI 和 Amazon 等领先人工智能公司的高性能基础模型(FM),以及构建生成式人工智能应用程序所需的一系列广泛功能,在维护隐私和安全的同时简化开发。本文将借助 Amazon Bedrock 上的大语言模型(例如 Anthropic 的 Claude2),通过预先自定义 Prompt 提示词,让大语言模型做基于文本的内容审核。

语音审核

Amazon Transcribe 提供语音识别服务,它使用机器学习模型将音频转换为文本。 Transcribe 毒性检测功能可用于检测音频中的不合适内容,例如在线游戏、社交聊天平台,直播间语音检测等。使用有害言论可能对个人、同龄群体和社区造成严重伤害,及时过滤有害语言有助于维护一个安全和包容的在线环境。该功能结合音频和文本两方面线索,识别和分类语音中包含的有害内容,涵盖性骚扰、仇恨言论、威胁、虐待、亵渎、侮辱等七大类别。与仅依赖文本的内容审核不同,Transcribe 毒性内容检测不仅检测语音转录的文字,还分析语音本身的语气和语调等特征,以更深入理解语音中的潜在恶意。这种双重判断机制使 Transcribe 毒性内容检测功能相比传统审核系统有很大的改进,可以实现更准确的毒性内容识别。对于在语音审核上有更高要求的客户,可以利用 Amazon Comprehend 或 Amazon Bedrock 的大语言模型(例如 Anthropic 的 Claude2),再做转录后基于文本的内容审核,以提高业务的安全合规。

整体架构

本方案整体架构如上图所示:

  1. 用户上传各类型文件(包括:文本、图像、视频、语音)到 Amazon S3 存储桶
  2. 文件成功上传存储桶后,监测到 S3 存储桶的事件变化(PUT Event),会自动触发 AWS Lambda
  3. AWS Lambda 根据文件类型执行相应的内容审核
    • a.使用 Amazon Rekognition 进行图像/视频数据的内容审核,包括:
      1. i.对不合规图像/视频数据进行审核
      2. ii.分析图像中的人脸相关信息,包括名人、年龄范围、面部的检测框、置信度值等属性
      3. iii.提取图片中的文本,再使用Comprehend、Bedrock进行文本审核
    • b.使用 Amazon Comprehend 对文本数据进行情绪分析、个人信息提取、毒性检测,包括:
      1. i.毒性检测,分析文本中的不合适内容,检测是否有包含脏话,暴力等相关内容
      2. ii.分析文本情绪,识别文本中的个人身份信息(PII)实体,如年龄、地址等信息
    • c.使用 Amazon Bedrock 中集成的大语言模型 Claude v2,通过对提示词自定义内容审核策略,对文本数据进行内容审核
    • d.使用 Amazon Transcribe 对语音进行毒性分类,类别包括脏话、仇恨言论、侮辱等;检测到的文本信息再使用 Comprehend、Bedrock 进行文本审核
    • e.使用 Amazon Translate 将文本语言转换为英文
  1. 通过 Amazon CloudWatch 监控 AWS Lambda 的每次执行,并将日志记录到 CloudWatch Logs 中
  2. 审核结果,部分以 JSON 格式存储至 S3

实验步骤

本次实验以 US East(N. Virginia) us-east-1 区域为例。

环境准备

Bedrock 权限申请

Amazon Bedrock 用户需要先请求访问模型,然后才能使用模型。 如果您想要添加用于文本、聊天和图像生成的其他模型,您需要请求访问 Amazon Bedrock 中的模型。请注意,只有具有所需 IAM 权限的用户才能管理此帐户的模型访问权限。

点击控制台的查找框,搜索 Amazon Bedrock,进入 Amazon Bedrock 的控制台界面,找到下图所示的“Model access”,点击“Manage model access”,可以看到 Amazon Bedrock 提供的模型,勾选我们需要的模型,并点击“Save changes”。设置好请求访问模型后,模型即刻便可访问。本次实验主要会用到 Anthropic Claude。

创建 S3 桶

从 AWS 控制台进入 S3 服务,创建一个存储桶,设置存储桶的“Bucket name”,其它选项保持默认,点击

注意,存储桶的名称必须全球唯一,并遵循存储桶的命名规范

创建好存储桶后,在桶中创建一个文件夹“content_moderation_test_data/”,用于存放测试数据。

创建 IAM 策略

每个 Lambda 函数都有一个与之关联的 IAM 角色。此角色定义允许该功能与其进行交互的其他 AWS 服务。

在 AWS 控制台中进入 IAM 服务,选择创建名为“bedrock”的策略。

创建名为 bedrock 的策略,策略配置如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",    
            "Action": "bedrock:*",
            "Resource": "*"
        }
    ]
}

创建并设置 Lambda

进入到 Lambda 控制台,按照以下配置创建一个新的函数。

  • 函数名称:填写你的函数名称,如 content_moderation
  • 运行时:选择 Python 3.10
  • 架构:选择 x86_64
  • 权限:创建具有基本 Lambda 权限的新角色
  • 点击创建函数

创建完 Lambda 函数之后,修改 Lambda 函数配置,方便我们后续进行测试。

点击已经建好的的 Lambda 函数,进入该函数的配置界面,修改 Lambda 函数的超时时间,设置为 15 分钟。

进入到该函数的权限界面,找到刚刚已经建好的角色“content_moderation_lambda-role-og6yztev”。

为该角色添加刚建好的“bedrock”策略和“AmazonRekognitionFullAccess”、“AmazonS3FullAccess”、“AmazonTranscribeFullAccess”、“ComprehendFullAccess”、“TranslateFullAccess”。

注意:这里是实验环境,所以给了服务的全部访问权限,请根据实际生产环境赋予相应的权限。

安装 Python 3.10,下载需要的安装包。配置 AWS CLI,将 zip 包上传到创建的 S3。

##下载Python3.10
wget https://www.python.org/ftp/python/3.10.12/Python-3.10.12.tgz 
tar xzf Python-3.9.10.tgz 
cd Python-3.10.12

##编译安装Python3.10
./configure --enable-optimizations
sudo make altinstall

##配置python3.10
sudo rm -f /usr/bin/python3
sudo ln -s /usr/local/bin/python3.10 /usr/bin/python

##下载boto3、easydict、langchain,并打包成zip,上传到S3存储桶后删除本地zip包
##将BUCKET_NAME换成您的S3存储桶
bucket='s3://BUCKET_NAME/'
pip install boto3 --target ./python
zip -r lambda_layer.zip ./python 

##上传到S3,并删除本地zip包
aws s3 cp ./lambda_layer.zip $bucket 
rm -r ./python ./lambda_layer.zip

在 Lambda 创建名为“content_moderation_layer”的 Layer 层,并将存储在 S3 存储桶中的 zip 文件上传到 Layer。

为 Lambda 函数添加 Layers,添加刚刚创建的名为“content_moderation_layer”的 Layer。

为 Lambda 函数添加 trigger。

配置 trigger 为 S3,存储桶 Bucket 选择刚创建的 S3 存储桶,将事件类型 event type 配置为“PUT”,确认后,点击“Add”。

进入该 Lambda 函数的配置 Monitor 中,点进“View CloudWatch logs”,并建名为“/aws/lambda/content moderation”的日志组。

Lambda 代码实现

完整代码和测试数据见 Github,将代码复制到 Lambda 函数的 lambda_function.py 中,并点击 Deploy 进行部署。主要功能模块如下:

1 . 从 S3 下载文件并读取内容

本次实验设计为通过 S3 上传事件触发 Lambda 自动开启审核流程,首先从 event 对象中获取 S3 存储桶名和文件名等相关参数信息。

bucketName = event["Records"][0]["s3"]["bucket"]["name"]
putObjectPathName = event["Records"][0]["s3"]["object"]["key"]

然后根据文件后缀判断文件类型,调用不同函数完成内容审核。

2. 调用 Rekognition 做图像审核

上传的图片内容将触发 Rekognition 的图像审核功能。DetectModerationLabels 来检测图像中是否有暴力血腥等不安全的内容,并返回标签 ModerationLabels 字段,其中包含标签、置信度等属性(当需要过滤包含裸体的图像,但不过滤包含暗示性内容的图像时,可通过设定合适的阈值和标签,来限制某些图像的显示);detect_faces 分析图像中的人脸,该接口会检测图像中存在的人脸。并返回年龄范围、面部以及不同器官的检测框及置信度值等属性;RecognizeCelebrities 来检测图像中的名人,也可以结合自定义面孔集合来实现某些地区禁止出现特定面孔的需求。

def image_moderation(bucketName, putObjectPathName):
    image = {'S3Object':{'Bucket':bucketName,'Name':putObjectPathName}}
    content_result = edict()
    rekognition = boto3.client('rekognition')
    # Image moderation
    content_result["Image_moderation_lable"] = rekognition.detect_moderation_labels(Image=image)
    # Face Dection on Image
    content_result["Image_Face_analysis_lable"] = rekognition.detect_faces(Image=image,Attributes=['ALL'])
    # Rekognition celebrities on Image
    content_result["Image_Celebrities_lable"] = rekognition.recognize_celebrities(Image=image)
    return content_result

在完整代码中,还有从图像中提取文本信息的接口 detect_text,该接口将图像中的文本提取出来再用后续的文本审核手段做文本检测。

3. 调用 Comprehend 做文本审核

上传的文本内容将触发 Comprehend 的文本审核功能,Comprehend 的 detect_toxic_content 方法对输入文本进行毒性内容检测;detect_sentiment 方法对同一文本进行情感分析;detect_pii_entities 方法识别文本中的个人身份信息(PII)实体,如年龄、地址等;使用 translate_text 将文本语言编码为英文。利用 Comprehend 服务对文本进行多项智能分析,包括毒性检测、情感分析和 PII 识别,为后续安全合规的手段提供支持。

def comprehend_dect(text):
    comprehend_analysis_dict = edict()   
    comprehend = boto3.client(service_name='comprehend')
    translate = boto3.client(service_name='translate')
    age = None
    # Text moderation
    response = comprehend.detect_toxic_content(TextSegments=text, LanguageCode='en')
    # Identify language and translat to English
    language_code = detect_language_result['Languages'][0]['LanguageCode']
    if language_code != 'en':
        # Translate text's language code to English
        response = translate.translate_text(Text=text, SourceLanguageCode=language_code, TargetLanguageCode="en")
        text = response["TranslatedText"]
    else:
        pass
    # Sentiment detection
    sentiment = comprehend.detect_sentiment(Text=text, LanguageCode= 'en')
    # Identify PII information
    pii_entities = comprehend.detect_pii_entities(Text=text, LanguageCode='en')  
    
    comprehend_analysis_dict['Sentiment'] = sentiment['Sentiment']
    comprehend_analysis_dict['SentimentScore'] = sentiment['SentimentScore']
    comprehend_analysis_dict["PII"] = pii_entities
    for entity in pii_entities['Entities']:
        if entity['Type'] == 'AGE':
            age = text[entity['BeginOffset']:entity['EndOffset']]
        break
    comprehend_analysis_dict["age"] = age
    
    return comprehend_analysis_dict

4. 调用 Bedrock 的 Claude v2 实现文本审核

上传的文本内容同样会触发使用 BedRock 提供的 Claude 大语言模型来做审核。通过自定义内容审核策略和输出模版,由大语言模型给出审核结果及理由。内容审核策略作为 Prompt 提示词,支持用户自定义。

def bedrock_modration(text):
    
    bedrock = boto3.client(service_name="bedrock-runtime")   

    inference_modifier = {'max_tokens_to_sample':4096, 
                          "temperature":0.5,
                          "top_k":250,
                          "top_p":1,
                          "stop_sequences": ["\n\nHuman"]}

    textgen_llm = Bedrock(model_id = "anthropic.claude-v2",
                    client = bedrock, 
                    model_kwargs = inference_modifier )
    

    # Create a prompt template that has multiple input variables
    moderation_policy = """
    1. Explicit Nudity: it contains Nudity, Graphic Male Nudity, Graphic Female Nudity, Sexual Activity, Illustrated Explicit Nudity and Adult Toys.
    2. Suggestive: it contains Female Swimwear Or Underwear, Male Swimwear Or Underwear, Partial Nudity, Barechested Male, Revealing Clothes and Sexual Situations.
    3. Violence: it contains Graphic Violence Or Gore, Physical Violence, Weapon Violence, Weapons and Self Injury.
    4. Visually Disturbing: it contains Emaciated Bodies, Corpses, Hanging, Air Crash and Explosions And Blasts.
    5. Rude Gestures: it contains Middle Finger.
    6. Drugs: it contains Drug Products, Drug Use, Pills and Drug Paraphernalia.
    7. Tobacco: it contains contain Tobacco Products and Smoking.
    8. Alcohol: it contains Drinking and Alcoholic Beverages.
    9. Gambling: it contains Gambling.
    10. Hate Symbols: it contains Nazi Party, White Supremacy and Extremist.
    """
    prompt_template = f"""
    The following is our company's content moderation policy, based on the moderation policy, we gather text information from the user uploaded text. Please answer the question with json format. 
            
    ###### moderation policy ######
    {moderation_policy}
            
    ###### text information ######
    {text}
            
    ###### Question ######
    Based on the following Moderation policy and QA, tell me if the content containes unsafe content, also give its category and reason. Please anwser the question with the following format and only put explanation into the reason field: 
    """

    prompt_template += """
    {
        "flag": "xxx",
        "category": "xxx",
        "reason": "the reason is ..."
    }
    """
    llm_response = textgen_llm(prompt_template)
    return llm_response

5. 调用 Transcribe 实现音频内容的审核

上传的语音文件将触发 Transcribe 的毒性检测功能。Transcribe 服务启动音频转录任务,并开启毒性内容检测;语音文件检测结果会存储到 S3,检测结果中包含毒性类别标签、置信度及转录文本。另外,由于 Transcribe 毒性检测的类别有限,且仅支持英文,转录后文本将调用 Bedrock 的大语言模型,进行基于文本的内容审核。

def Audio_moderation(bucketName, putObjectPathName, file_uri):
    transcribe_job_name = putObjectPathName.split("/")[-1] + random_char
    outputkey = putObjectPathName.split(".")[0] + random_char + ".json"
    
    transcribe.start_transcription_job(
        TranscriptionJobName = transcribe_job_name,
        Media = {
            'MediaFileUri': file_uri
        },
        OutputBucketName = bucketName,
        OutputKey = outputkey, 
        LanguageCode = 'en-US', 
        ToxicityDetection = [ 
            { 
                'ToxicityCategories': ['ALL']
            }
        ]
    )
    while True:
        status = transcribe.get_transcription_job(TranscriptionJobName = transcribe_job_name)
        if status['TranscriptionJob']['TranscriptionJobStatus'] in ['COMPLETED', 'FAILED']:
            break
    # Toxicity detection
    response = s3.get_object(Bucket=bucketName, Key=outputkey)
    json_data = edict(json.loads(response['Body'].read()))
    content_result["Toxicity_lablel"] = json_data.results.toxicity_detection
    return content_result

测试结果

说明:Lambda 的最长运行时间为 15 分钟,文件过大可能会导致超时,对于较长的视频文件,这里会以单独的 python 文件运行内容审核,文件位置:链接。鉴于审核结果过长,截图仅是关键的部分测试结果,全部的审核结果见这里

下图是上传到 S3 存储桶的数据,包含图像、文本、音频、视频文件。

其中,图像文件的部分审核结果如下图所示。

音频文件审核如下图所示。

下图为不安全的文本文件内容审核结果。

下图为安全的文本文件内容审核结果。

清理资源

最后,可通过删除创建的 AWS Lambda 函数、S3 存储桶以及创建 Lambda 时所创建的角色和策略,完成资源的清理。

总结

本方案使用亚马逊云科技多种托管的 AIML 服务,快速构建覆盖文本、图像、视频、语音等全方位的智能化内容审核系统,并且使用 Amazon Lambda 实现了无服务器的架构,用户可以根据实际业务需求方便集成到各种场景。

本篇作者

马佳

亚马逊云科技解决方案架构师,负责基于亚马逊云科技云平台解决方案的设计和咨询,AWS 人工智能机器学习领域成员。在机器学习、深度学习及自动驾驶感知领域,拥有丰富的理论及算法实践工程经验。

汪其香

AWS 解决方案架构师,负责基于 AWS 云计算方案的架构咨询和设计实现,具有丰富的解决客户实际问题的经验,同时热衷于深度学习的研究与应用。