如何使用AWS和ChatGPT创建最智能的多语言虚拟助理

354 阅读12分钟

上周ChatGPT发布了,每个人都在尝试惊人的事情。我也开始玩它,想试试它如何使用AWSAI服务进行整合,结果是AWSome!

在这篇文章中,我将一步步解释我是如何创建这个项目的,所以你也可以这样做

最重要的是,你不需要成为一个人工智能专家来创建这个项目!我将假设你已经知道什么是聊天室!

我将假设你已经知道ChatGPT是什么,并且有一个账户来玩AWS。

GitHub logo robertgv /chatgpt-aws

ChatGPT + AWS

上周ChatGPT发布了,每个人都在尝试令人惊讶的事情。我也开始玩它,想试试它如何使用AWSAI服务进行整合,结果是AWSome!

在这篇文章中,我将一步步解释我是如何创建这个项目的,所以你也可以这样做:

dev.to/aws-builder…

最重要的是,你不需要成为人工智能专家就可以创建这个项目!

项目的步骤

Image description

我把这个项目分成了8个步骤:

  1. 录制一段音频并保存为WAV格式
  2. 将音频文件上传到Amazon S3
  3. 使用Amazon Transcribe转录并检测保存在S3中的音频的语言
  4. 亚马逊Transcribe将转录本保存在亚马逊S3中
  5. 将转录内容发送到ChatGPT
  6. 从ChatGPT接收文本答案并删除代码块
  7. 使用在S3中检测到的语言将文本转换为音频...

项目的步骤

Image description

我把这个项目分为8个步骤:

  1. 录制音频并保存为WAV格式
  2. 将音频文件上传到Amazon S3
  3. 使用Amazon Transcribe转录并检测保存在S3中的音频的语言
  4. 亚马逊Transcribe在亚马逊S3中保存转录的内容
  5. 将转录内容发送到ChatGPT
  6. 从ChatGPT接收文本答案并删除代码块
  7. 使用Amazon Polly将文本转换为音频,并使用步骤3中检测到的语言,下载MP3格式的音频
  8. 复制音频文件

在开始之前,我们需要定义一般的参数,你需要创建这些参数,以后在下面的代码中替换。这个凭证的创建将在接下来的步骤中解释。

# ChatGPT params
chatGPT_session_token = "<SESSION-TOKEN>"

# AWS params
aws_access_key_id = "<ACCESS-KEY-ID>"
aws_secret_access_key = "<SECRET-ACCESS-KEY>"
aws_default_region = "<AWS-REGION>"
aws_default_s3_bucket = "<S3-BUCKET>"

# Voice recording params
samplerate = 48000
duration = 4 #seconds

进入全屏模式 退出全屏模式

1.录制一段音频并以WAV格式保存

首先,我们需要录制音频,在那里我们将提出我们希望ChatGPT回答的问题。为此,我们将使用软件包 声音设备.确保你在操作系统的默认配置中选择了正确的麦克风。
在这种情况下,它将记录声音的时间是4秒。如果你想增加或减少这个时间,只需修改参数duration的值。
脚本将把音频保存在当前工作目录下一个名为audio的文件夹中。如果这个文件夹不存在,它将使用os模块创建它。

def record_audio(duration, filename):
    print("[INFO] Start of the recording")
    mydata = sd.rec(int(samplerate * duration), samplerate=samplerate,channels=1, blocking=True)
    print("[INFO] End of the recording")
    sd.wait()
    sf.write(filename, mydata, samplerate)
    print(f"[INFO] Recording saved on: {filename}")

#Check if folder "audios" exists in current directory, if not then create it
if not os.path.exists("audio"):
    os.makedirs("audio")

# Create a unique file name using UUID
filename = f'audio/{uuid.uuid4()}.wav'

record_audio(duration, filename)

进入全屏模式 退出全屏模式

2.上传音频文件到Amazon S3

在这一步,首先我们需要创建一个Amazon S3 Bucket。为此,我们去AWS控制台,搜索Amazon S3服务。然后点击 "创建桶"

我们需要把我们的桶的名字(桶的名字必须在所有AWS地区的所有AWS账户中是唯一的),并选择AWS地区。

Image description

其余的参数,我们可以把它们作为默认值。最后,点击页面底部的 "创建水桶"

在开始的参数部分,我们需要用桶的名称和选择的区域来替换这些值:

aws_default_region = "<AWS-REGION>"
aws_default_s3_bucket = "<S3-BUCKET>"

进入全屏模式 退出全屏模式

下一步是创建一个新的用户,我们将用boto3来访问这个S3桶。Boto3是亚马逊网络服务(AWS)针对Python的软件开发工具包(SDK),它允许Python开发人员编写软件,利用像Amazon S3和Amazon EC2这样的服务。

为了创建新的用户,我们在AWS控制台中搜索IAM。然后点击左边菜单中访问管理下的用户

Image description

点击右上角的 "添加用户"。我们需要提供一个用户名,然后点击访问密钥的复选框**- 程序化访问**。

Image description

然后点击 "下一步":权限(Permissions)。这里直接点击附加现有政策,然后点击创建政策

Image description

这里我想说的是,我们可以直接选择名为AmazonS3FullAccess的策略,这样就可以了,但这违背了最小权限的原则。在这种情况下,我们将只提供对我们之前创建的桶的访问。

创建策略页面,点击选择服务,搜索S3并点击它。然后在行动上点击选项:

  • ListBucket
  • 获取对象
  • 删除对象
  • 放置对象

在 "资源"上点击 "特定",然后在 "桶 "上点击 "添加ARN",放入我们之前创建的桶的名称并点击 "添加"。在对象上,也点击添加ARN,放上之前创建的水桶名称,在对象名称上点击任何复选框。

Image description

然后点击 "下一步":标签下一步:审查。最后,给新政策起个名字,点击创建政策

一旦政策被创建,回到创建用户的页面,搜索创建的新政策。如果它没有出现,点击刷新按钮。

Image description

然后点击 "下一步":标签下一步:审查。最后,审查一切正常,点击创建用户

Image description

在下一页,我们将得到访问密钥ID秘密访问密钥。请确保保存它们(特别是秘密访问密钥),不要分享它们。在开始的参数部分,我们需要替换这些值:

aws_access_key_id = "<ACCESS-KEY-ID>"
aws_secret_access_key = "<SECRET-ACCESS-KEY>"

进入全屏模式 退出全屏模式

这样我们就有了一个有权限写进之前创建的S3桶的用户。

# Connect to Amazon S3 using Boto3
def get_s3_client():
    return(boto3.client('s3', region_name=aws_default_region, aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key))

def upload_file_to_s3(filename):
    s3_client = get_s3_client()
    try:
        with open(filename, "rb") as f: 
            s3_client.upload_fileobj(f, aws_default_s3_bucket, filename)
            print(f"[INFO] File has been uploaded successfully in the S3 bucket: '{aws_default_s3_bucket}'")
    except:
        raise ValueError(f"[ERROR] Error while uploading the file in the S3 bucket: '{aws_default_s3_bucket}'")

upload_file_to_s3(filename)

进入全屏模式 退出全屏模式

3-4.使用Amazon Transcribe转录并检测保存在S3中的音频的语言

亚马逊Transcribe是AWS的人工智能(AI)服务,可以让你轻松地将语音转换为文本。利用自动语音识别(ASR)技术,您可以将Amazon Transcribe用于各种业务应用,包括转录基于语音的客户服务电话,在音频/视频内容上生成字幕,以及对音频/视频内容进行(基于文本的)内容分析。

为了能够在上一步创建的IAM用户中使用Amazon Transcribe,我们需要通过IAM策略提供对它的访问。

为此,我们需要到AWS控制台的IAM,点击左侧菜单上的用户,然后点击之前创建的用户。点击添加权限,然后直接附加现有策略。搜索AmazonTranscribe并点击AmazonTranscribeFullAccess的复选框。

Image description

点击 "下一步":审查添加权限

在这一点上,这个用户应该有两个附加政策:

Image description

在添加这个额外的权限后,你需要修改/更新访问密钥ID秘密访问密钥

在下面的python代码中,我们通过boto3包使用Amazon Transcribe将音频中记录的语音转录为文本。亚马逊转录还可以检测音频中使用的语言。

在这里你可以阅读boto3文档中关于TranscribeService的所有文档。

转录的内容被保存在Amazon S3的JSON文件中。你可以选择把你的成绩单保存在你自己的Amazon S3桶里,或者让Amazon Transcribe使用一个安全的默认桶。在我的案例中,我选择的是默认选项,即在拥有的Amazon S3桶上。如果我们选择默认选项,作业到期(90天)时,成绩单会被删除。如果我们想在这个到期日之后保留成绩单,我们必须下载它。

# Generate UUID for the job id
job_id = str(uuid.uuid4())

# Connect to Amazon Transcribe using Boto3
def get_transcribe_client():
    return(boto3.client('transcribe', region_name=aws_default_region, aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key))

def get_text_from_audi(filename):
    transcribe = get_transcribe_client()
    print("[INFO] Starting transcription of the audio to text")
    transcribe.start_transcription_job(TranscriptionJobName=job_id, Media={'MediaFileUri': f"https://{aws_default_s3_bucket}.s3.{aws_default_region}.amazonaws.com/{filename}"}, MediaFormat='wav', IdentifyLanguage=True)
    print("[INFO] Transcribing text: *",end="")
    while True:
        status = transcribe.get_transcription_job(TranscriptionJobName=job_id)
        if status['TranscriptionJob']['TranscriptionJobStatus'] in ['COMPLETED', 'FAILED']:
            break
        print("*",end='')
        time.sleep(2)
    print("") #End of line after loading bar
    if status['TranscriptionJob']['TranscriptionJobStatus'] == 'COMPLETED':
        response = urllib.request.urlopen(status['TranscriptionJob']['Transcript']['TranscriptFileUri'])
        data = json.loads(response.read())
        language_detected = data['results']['language_identification'][0]['code']
        transcript = data['results']['transcripts'][0]['transcript']
        print(f"[INFO] Transcription completed!")
        print(f"[INFO] Transcript language: {language_detected}")
        print(f"[INFO] Transcript text: {transcript}")
        return(transcript, language_detected)
    else:
        raise ValueError("[ERROR] The process to convert audio to text using Amazon Transcribe has failed.")

transcript, language_detected = get_text_from_audi(filename)

进入全屏模式 退出全屏模式

5.将誊本发送到ChatGPT

一旦我们从亚马逊转录处收到誊本,我们需要将其发送到ChatGPT。为此,我使用了revChatGPT软件包。要使用这个包,我们需要对ChatGPT进行认证,这可以使用用户名密码或使用session_token来完成。在我的例子中,因为我使用谷歌的OAuth认证方法,我将使用会话令牌

为了获得会话令牌,我们需要登录ChatGPT,然后点击F12或右键单击并检查。然后搜索应用程序标签,在左边的菜单中搜索Cookies。选择网站*chat.openai.com*,然后搜索名称为**__Secure-next-auth.session-token**的cookie,并复制这个cookie的值。

Image description

在一开始的参数部分,我们需要用你的会话令牌值替换这个值:

chatGPT_session_token = "<SESSION-TOKEN>"

进入全屏模式 退出全屏模式

如果你想使用电子邮件密码作为认证方法,你可以查看这里的步骤,如何做到这一点。

一旦完成这些,我们应该可以用Python连接到ChatGPT。

def get_gpt_answer(prompt):
    print(f"[INFO] Sending transcript to ChatGPT")
    config = {"email": "<API-KEY>","session_token": chatGPT_session_token}
    chatbot = Chatbot(config, conversation_id=None)
    chatbot.refresh_session()
    response = chatbot.get_chat_response(prompt, output="text")["message"]
    print(f"[INFO] ChatGPT answer: {response}")
    return(response)

chatgpt_answer = get_gpt_answer(transcript)

进入全屏模式 退出全屏模式

6.从ChatGPT接收文本答案并删除代码块

一旦我们从ChatGPT得到答案,可以是我们得到一个或多个代码块。在这种情况下,我正在应用一个regex函数来删除这些代码块。

在这里,你也可以添加你自己的规则,来过滤或清理来自ChatGPT的答案。

def clean_audio_text(text):
    # Clean the code chuncks from the audio using regex
    result = re.sub(r"```

[^\S\r\n]*[a-z]*\n.*?\n

```", '', text, 0, re.DOTALL)
    return(result)

进入全屏模式 退出全屏模式

7.使用Amazon Polly将文本转换为音频,使用步骤3上检测到的语言,并下载MP3格式的音频

亚马逊Polly使用深度学习技术来合成自然的人类语音,所以我们可以将文本转换为语音。

从ChatGPT清理完答案后,我们就可以把它发送到Amazon Polly

为了能够用之前创建的用户使用Amazon Polly,我们需要使用一个策略来提供对它的访问,就像我们在前一步对Amazon Transcribe所做的那样。

为此,我们需要进入AWS控制台的IAM,点击左侧菜单上的用户,然后点击之前创建的用户。然后点击添加权限,然后直接附加现有政策。搜索AmazonPolly并点击AmazonPollyFullAccess的复选框。

Image description

点击 "下一步":审查添加权限

在这一点上,这个用户应该有3个附加策略:

Image description

Amazon Polly支持多种语言和不同性别。在这种情况下,我提供的代码已经预先定义了3种语言:英语、西班牙语和加泰罗尼亚语。另外,请注意,对于每种语言,你可以根据国家的不同而有不同的变化。例如,对于英语,我们有en-USen-GBen-IN和其他。

所有可用的语言和变化的完整列表可在这里找到。

在向Amazon Polly发送文本后,我们将收到一个包含合成语音的流。

def get_polly_client():
    return boto3.client('polly', region_name=aws_default_region, endpoint_url=f"https://polly.{aws_default_region}.amazonaws.com", aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key)

def generate_audio(polly, text, output_file, voice, format='mp3'):
    text = clean_audio_text(text)
    resp = polly.synthesize_speech(Engine='neural', OutputFormat=format, Text=text, VoiceId=voice)
    soundfile = open(output_file, 'wb')
    soundBytes = resp['AudioStream'].read()
    soundfile.write(soundBytes)
    soundfile.close()
    print(f"[INFO] Response audio saved in: {output_file}")

def get_speaker(language_detected):
    # Get speaker based on the language detected by Amazon Transcribe (more info about available voices: https://docs.aws.amazon.com/polly/latest/dg/voicelist.html)
    voice = ""
    if language_detected == "en-US":
        voice = "Joanna"
    elif language_detected == "en-GB":
        voice = "Amy"
    elif language_detected == "en-IN":
        voice = "Kajal"
    elif language_detected == "ca-ES":
        voice = "Arlet"
    elif language_detected == "es-ES":
        voice = "Lucia"
    elif language_detected == "es-MX":
        voice = "Mia"
    elif language_detected == "es-US":
        voice = "Lupe"
    else:
        voice = "Joanna"
        print(f"[WARNING] The language detected {language_detected} is not supported on this code. In this case the default voice is Joanna (en-US).")
    print(f"[INFO] Speaker selected: {voice}")
    return(voice)

polly = get_polly_client()
voice = get_speaker(language_detected)
output_file = f"audio/{job_id}.mp3"
generate_audio(polly, chatgpt_answer, output_file,voice=voice)

进入全屏模式 退出全屏模式

8.复制音频文件

最后,我们只需要播放Amazon Polly的音频结果。

根据你的操作系统或从哪里运行这个功能,它可能无法工作。在我的例子中,当我从macOS的终端运行*speak_script(output_file)函数时,它可以工作。如果你使用的是像Jupyter Notebook这样的笔记本,那么请使用speak_notebook(output_file)*函数。

def speak_notebook(output_file):
    print(f"[INFO] Start reproducing response audio")
    display(Audio(output_file, autoplay=True))

def speak_script(output_file):
    print(f"[INFO] Start reproducing response audio")
    return_code = subprocess.call(["afplay", output_file])

speak_script(output_file)

进入全屏模式 退出全屏模式

输出示例

如果我们遵循了前面所有的步骤,我们应该已经准备好开始玩我们新的多语言虚拟助手了。为了向你展示输出的样子,我录下了自己问*"什么是亚马逊网络服务?"*,你可以清楚地看到这正是亚马逊Transcribe生成的成绩单,然后是ChatGPT提供的答案。

$ python3 ChatGPT-AWS.py
[INFO] Start of the recording
[INFO] End of the recording
[INFO] Recording saved on: audio/6032133a-ec26-4fa0-8d0b-ad705293be09.wav
[INFO] File has been uploaded successfully in the S3 bucket: 'chatgpt-transcribe'
[INFO] Starting transcription of the audio to text
[INFO] Transcribing text: *********
[INFO] Transcription completed!
[INFO] Transcript language: en-US
[INFO] Transcript text: What is Amazon Web Services?
[INFO] Sending transcript to ChatGPT
[INFO] ChatGPT answer: Amazon Web Services (AWS) is a cloud computing platform that provides a wide range of services, including computing, storage, and content delivery. AWS offers these services on a pay-as-you-go basis, allowing businesses and individuals to access the resources they need without having to invest in expensive infrastructure. AWS is widely used by organizations of all sizes, from small startups to large enterprises.
[INFO] Speaker selected: Joanna
[INFO] Response audio saved in: audio/168a94de-1ba2-4f65-8a4c-d3c9c832246d.mp3
[INFO] Start reproducing response audio

进入全屏模式 退出全屏模式

我希望你能像我在构建和玩弄这些服务时一样喜欢它。我认为这些最先进的技术有很多机会/潜力,当我们一起使用所有这些技术时,其结果是AWSome!