Amazon Web Services 한국 블로그

Amazon Comprehend – 신규 유해성 검출 기능 출시

Amazon Comprehend를 사용하면 기계 학습 전문가가 아니더라도 텍스트에서 인사이트를 추출할 수 있습니다. Comprehend는 내장 모델을 사용하여 입력 문서의 구문을 분석하고 항목, 이벤트, 핵심 문구, 개인 식별 정보(PII) 및 특정 항목(예: 브랜드 또는 제품)과 관련된 감정 또는 전반적인 감정을 찾을 수 있습니다.

오늘은 유해성 콘텐츠를 감지하는 기능을 추가합니다. 이 새로운 기능은 최종 사용자에게 더 안전한 환경을 구축하는 데 도움이 됩니다. 예를 들어, 유해성 검출 기능을 사용하여 댓글과 같은 외부 요인에 노출된 애플리케이션의 안전성을 개선할 수 있습니다. 생성형 AI를 사용하는 경우, 유해성 검출 기능을 사용하여 대규모 언어 모델(LLM)의 입력 프롬프트와 출력 응답을 확인할 수 있습니다.

AWS Command Line Interface(AWS CLI)AWS SDK에서 유해성 검출 기능을 사용할 수 있습니다. AWS SDK에 속하는 AWS CLI를 사용하는 몇 가지 예제를 통해 이 기능이 실제로 어떻게 작동하는지 살펴보고 LLM의 사용을 확인해 보겠습니다.

AWS CLI를 통한 Amazon Comprehend 유해성 검출 기능 사용
AWS CLI의 새로운
detect-toxic-content 하위 명령은 텍스트 내 유해성을 검출합니다. 출력에는 입력의 각 텍스트 세그먼트마다 하나씩 있는 레이블 목록이 포함됩니다. 각 텍스트 세그먼트에 대해 레이블과 점수(0~1점)가 포함된 목록이 제공됩니다.

Amazon Comprehend 유해성 검출 API

예를 들어, 이 AWS CLI 명령은 하나의 텍스트 세그먼트를 분석하여 다음과 같이 하나의 Labels 섹션을 반환하고 해당 세그먼트에 대한 전체 Toxicity 점수(범위: 0~1)를 반환합니다.

aws comprehend detect-toxic-content --language-code en --text-segments Text="'Good morning, it\'s a beautiful day.'"
{
    "ResultList": [
        {
            "Labels": [
                {
                    "Name": "PROFANITY",
                    "Score": 0.00039999998989515007
                },
                {
                    "Name": "HATE_SPEECH",
                    "Score": 0.01510000042617321
                },
                {
                    "Name": "INSULT",
                    "Score": 0.004699999932199717
                },
                {
                    "Name": "GRAPHIC",
                    "Score": 9.999999747378752e-05
                },
                {
                    "Name": "HARASSMENT_OR_ABUSE",
                    "Score": 0.0006000000284984708
                },
                {
                    "Name": "SEXUAL",
                    "Score": 0.03889999911189079
                },
                {
                    "Name": "VIOLENCE_OR_THREAT",
                    "Score": 0.016899999231100082
                }
            ],
            "Toxicity": 0.012299999594688416
        }
    ]
}

예상대로 모든 점수는 0에 가깝고 이 텍스트에서는 유해성이 검출되지 않았습니다.

입력을 파일로 전달하기 위해 먼저 AWS CLI --generate-cli-skeleton 옵션을 사용하여 detect-toxic-content 명령에서 사용하는 JSON 구문의 스켈레톤을 다음과 같이 생성합니다.

aws comprehend detect-toxic-content --generate-cli-skeleton
{
    "TextSegments": [
        {
            "Text": ""
        }
    ],
    "LanguageCode": "en"
}

출력을 파일에 쓰고 세 개의 텍스트 세그먼트를 추가합니다(유해성 콘텐츠에 어떤 일이 발생하는지 보여주는 데 사용되는 텍스트는 여기에 표시하지 않겠습니다). 이번에는 다양한 수준의 유해성 콘텐츠가 발견되었습니다. 각 Labels 섹션은 해당 입력 텍스트 세그먼트와 관련이 있습니다.

aws comprehend detect-toxic-content --cli-input-json file://input.json
{
    "ResultList": [
        {
            "Labels": [
                {
                    "Name": "PROFANITY",
                    "Score": 0.03020000085234642
                },
                {
                    "Name": "HATE_SPEECH",
                    "Score": 0.12549999356269836
                },
                {
                    "Name": "INSULT",
                    "Score": 0.0738999992609024
                },
                {
                    "Name": "GRAPHIC",
                    "Score": 0.024399999529123306
                },
                {
                    "Name": "HARASSMENT_OR_ABUSE",
                    "Score": 0.09510000050067902
                },
                {
                    "Name": "SEXUAL",
                    "Score": 0.023900000378489494
                },
                {
                    "Name": "VIOLENCE_OR_THREAT",
                    "Score": 0.15549999475479126
                }
            ],
            "Toxicity": 0.06650000065565109
        },
        {
            "Labels": [
                {
                    "Name": "PROFANITY",
                    "Score": 0.03400000184774399
                },
                {
                    "Name": "HATE_SPEECH",
                    "Score": 0.2676999866962433
                },
                {
                    "Name": "INSULT",
                    "Score": 0.1981000006198883
                },
                {
                    "Name": "GRAPHIC",
                    "Score": 0.03139999881386757
                },
                {
                    "Name": "HARASSMENT_OR_ABUSE",
                    "Score": 0.1777999997138977
                },
                {
                    "Name": "SEXUAL",
                    "Score": 0.013000000268220901
                },
                {
                    "Name": "VIOLENCE_OR_THREAT",
                    "Score": 0.8395000100135803
                }
            ],
            "Toxicity": 0.41280001401901245
        },
        {
            "Labels": [
                {
                    "Name": "PROFANITY",
                    "Score": 0.9997000098228455
                },
                {
                    "Name": "HATE_SPEECH",
                    "Score": 0.39469999074935913
                },
                {
                    "Name": "INSULT",
                    "Score": 0.9265999794006348
                },
                {
                    "Name": "GRAPHIC",
                    "Score": 0.04650000110268593
                },
                {
                    "Name": "HARASSMENT_OR_ABUSE",
                    "Score": 0.4203999936580658
                },
                {
                    "Name": "SEXUAL",
                    "Score": 0.3353999853134155
                },
                {
                    "Name": "VIOLENCE_OR_THREAT",
                    "Score": 0.12409999966621399
                }
            ],
            "Toxicity": 0.8180999755859375
        }
    ]
}

AWS SDK를 통한 Amazon Comprehend 유해성 검출 기능 사용
AWS CLI를 통해 수행했던 것과 마찬가지로 AWS SDK를 사용하여 애플리케이션의 유해성을 프로그래밍 방식으로 검출할 수 있습니다. 다음 Python 스크립트는 AWS SDK for Python(Boto3)을 사용하여 텍스트 세그먼트의 유해성을 검출하고 지정된 임계값보다 점수가 큰 경우 레이블을 인쇄합니다. 코드에서 두 번째 및 세 번째 텍스트 세그먼트의 콘텐츠를 삭제하고 그 대신 ***를 입력했습니다.

import boto3

comprehend = boto3.client('comprehend')

THRESHOLD = 0.2
response = comprehend.detect_toxic_content(
    TextSegments=[
        {
            "Text": "You can go through the door go, he's waiting for you on the right."
        },
        {
            "Text": "***"
        },
        {
            "Text": "***"
        }
    ],
    LanguageCode='en'
)

result_list = response['ResultList']

for i, result in enumerate(result_list):
    labels = result['Labels']
    detected = [ l for l in labels if l['Score'] > THRESHOLD ]
    if len(detected) > 0:
        print("Text segment {}".format(i + 1))
        for d in detected:
            print("{} score {:.2f}".format(d['Name'], d['Score']))

Python 스크립트를 실행합니다. 출력에는 두 번째 및 세 번째 텍스트 세그먼트에서 검출된 레이블과 점수가 포함됩니다. 첫 번째 텍스트 세그먼트에서는 유해성이 검출되지 않습니다.

Text segment 2
HATE_SPEECH score 0.27
VIOLENCE_OR_THREAT score 0.84
Text segment 3
PROFANITY score 1.00
HATE_SPEECH score 0.39
INSULT score 0.93
HARASSMENT_OR_ABUSE score 0.42
SEXUAL score 0.34

LLM을 통한 Amazon Comprehend 유해성 검출 기능 사용
이 블로그 게시물에 설명된 대로 Amazon SageMaker JumpStart를 사용하여 Mistral 7B 모델을 배포했습니다.

모델 응답의 유해성을 방지하기 위해 다음 세 가지 함수로 Python 스크립트를 작성했습니다.

  • query_endpoint는 SageMaker JumpStart에서 배포한 엔드포인트를 사용하여 Mistral 7B 모델을 간접적으로 호출합니다.
  • check_toxicity는 Comprehend를 사용하여 텍스트에서 유해성을 검출하고 검출된 레이블 목록을 반환합니다.
  • avoid_toxicity는 검출된 레이블 목록의 입력을 받아 유해성을 방지하기 위해 수행해야 할 작업을 설명하는 메시지를 반환합니다.

LLM에 대한 쿼리는 입력 프롬프트에서 유해성이 검출되지 않는 경우에만 진행됩니다. 그런 다음, LLM의 응답은 출력에서 유해성이 검출되지 않는 경우에만 인쇄됩니다. 유해성이 검출되는 경우, 스크립트는 입력 프롬프트를 수정하는 방법을 제안합니다.

Python 스크립트의 코드는 다음과 같습니다.

import json
import boto3

comprehend = boto3.client('comprehend')
sagemaker_runtime = boto3.client("runtime.sagemaker")

ENDPOINT_NAME = "<REPLACE_WITH_YOUR_SAGEMAKER_JUMPSTART_ENDPOINT>"
THRESHOLD = 0.2


def query_endpoint(prompt):
    payload = {
        "inputs": prompt,
        "parameters": {
            "max_new_tokens": 68,
            "no_repeat_ngram_size": 3,
        },
    }
    response = sagemaker_runtime.invoke_endpoint(
        EndpointName=ENDPOINT_NAME, ContentType="application/json", Body=json.dumps(payload).encode("utf-8")
    )
    model_predictions = json.loads(response["Body"].read())
    generated_text = model_predictions[0]["generated_text"]
    return generated_text


def check_toxicity(text):
    response = comprehend.detect_toxic_content(
        TextSegments=[
            {
                "Text":  text
            }
        ],
        LanguageCode='en'
    )

    labels = response['ResultList'][0]['Labels']
    detected = [ l['Name'] for l in labels if l['Score'] > THRESHOLD ]

    return detected


def avoid_toxicity(detected):
    formatted = [ d.lower().replace("_", " ") for d in detected ]
    message = (
        "Avoid content that is toxic and is " +
        ", ".join(formatted) + ".\n"
    )
    return message


prompt = "Building a website can be done in 10 simple steps:"

detected_labels = check_toxicity(prompt)

if len(detected_labels) > 0:
    # Toxicity detected in the input prompt
    print("Please fix the prompt.")
    print(avoid_toxicity(detected_labels))
else:
    response = query_endpoint(prompt)

    detected_labels = check_toxicity(response)

    if len(detected_labels) > 0:
        # Toxicity detected in the output response
        print("Here's an improved prompt:")
        prompt = avoid_toxicity(detected_labels) + prompt
        print(prompt)
    else:
        print(response)

이제 스크립트의 샘플 프롬프트를 통해 유해성 응답을 받을 일은 없겠지만 만약 문제가 발생하더라도 이를 확인하고 완화하는 자동 프로세스를 설정할 수 있기 때문에 안심할 수 있습니다.

가용성 및 요금
Amazon Comprehend의 유해성 검출 기능은 현재 미국 동부(버지니아 북부), 미국 서부(오레곤), 유럽(아일랜드) 및 아시아 태평양(시드니) 등 일부 AWS 리전에서 사용할 수 있습니다.

유해성 검출 기능 사용 시 장기 약정은 없으며, 100자 단위(1단위=100자)로 입력한 문자 수에 따라 요금을 지불하고 요청 건당 최소 3단위(300자)의 요금이 부과됩니다. 자세한 내용은 Amazon Comprehend 요금을 참조하세요.

유해성 검출 기능을 통해 온라인 커뮤니티의 안전성을 높이고 애플리케이션의 LLM 도입 절차를 간소화하세요.

Danilo