亚马逊AWS官方博客

使用 Amazon SageMaker 和 Bedrock 构建营销场景端到端应用

现如今 AIGC 爆火出圈,其智能化、人性化的交互方式和惊人的创作能力,让人们对 AI 的未来充满期待。这种以创造力和智慧而非纯计算力见长的 AI,正在缩小人与机器的界限,展示出令人欣喜的未来景象。其不仅被技术和产业界竞相追逐,让全球各大科技企业都在积极拥抱 AIGC,不断推出相关的技术、平台和应用,同时 AI 也引发全民关注,茶余饭后人们都在讨论 AI 会为我们的工作、生活带来哪些改变。

那么,AIGC 究竟是什么?应用场景都有哪些?

AIGC(AI-Generated Content,人工智能生产内容)代表 AI 技术发展的新趋势,通过大量的训练数据和生成算法模型,自动生成文本、图片、音乐、视频、3D 交互内容等各种形式的内容。换言之,AIGC 正在加速成为 AI 领域的商业新边界。AIGC 如何工程化落地,也是我们一直探索的方向。

为了让用户更清晰地理解和掌握 AIGC 的使用,我们基于营销场景,构建了端到端的 AIGC 解决方案。从前端页面,后端处理,到 AI 模型调研,完整地提供了每一步实现方式(包括源代码和注释)。

下面让我们开启 AIGC 之旅。

一、价值驱动 — 业务聚焦

AIGC 作为当下最热门的技术方向,其中文本生成、图像生成也是目前工程化最成熟的两大类,可以广泛服务于各个行业的诸多业务场景。来源于 2023 年 2 月的 IDC 全球 CIO 快速调研结果:

  • 金融行业、电商零售、能源行业、医疗行业、法律行业头部机构会在 1 年内尝试引入大模型以及生成式 AI 能力;
  • 首先在相对成熟的场景中引入;
  • 驱动力来源于竞争压力,希望获取先发竞争优势。
  • 过去 5 年部署的 AI 应用,都有可能被新一代 AI 更新换代。

本文我们针对“营销应用”和“设计应用”两个方向进行展开。

业务场景分类

业务场景又细分为:文档和文案生成产品创意设计产品营销素材生成三部分。接下来,我们逐一介绍三个场景。

1. 文档和文案生成

营销文案的创作,是频繁且重复的工作,需要耗费大量的人力成本。而 AIGC 生于互联网,且更懂互联网,只要提供产品亮点,提示词(Prompt),即可由大语言模型(LLM)帮助我们完成。

下面就是几个营销文案样例。输入提示词,并选择期望的文案风格即可。

2. 产品创意设计

自 2022 年 8 月,Stable Diffusion 的首次发布,即引爆了整个互联网。从一张骑马的宇航员,到无处不在的二次元深渊橘。人们通过各种 prompt,来完成无限的艺术想象。

随着更多人的关注和贡献,也有越来越多的微调模型,可以提供细分领域的场景。下图就是通过工业设计风格的模型,设计出的产品创意图。也可以通过线稿,生成产品设计图片,这可以大大降低设计师的绘画成本。

3. 产品营销素材生成

在创意设计之外,产品背景更换,也是 AI 助力营销场景中,特别有价值的部分。根据不同的风格需求,更换对应的背景,可以大大降低实景拍摄的成本和实效性。也可以让提供给终端客户,根据个性化需求,在不同背景下,即时预览产品效果。增加购买成功率。

下面场景中,左侧是实拍图片,右侧是 AIGC 背景更换后效果。

二、深入浅出 — 原理解析

在初步了解了 AIGC 在业务场景的能力之后,我们从技术角度,针对每一个环节,进行详细的讲解。希望能通过本文,使读者有一个清晰的 AI 实施架构,并能根据文章的思路,结合到实际生产中。

本文就以下面几个维度,逐项开展:

  1. 文档和文案生成详解
  2. 产品创意设计详解
  3. 产品营销素材生成详解
  4. 前端应用 UI 代码解析
  5. 应用服务端代码解析
  6. 基于Amazon Bedrock的营销场景应用

注释: 为方便大家阅读,每小结内容结构为: Web UI 截图 + 技术架构图 + 源代码解析

为了完整的感受 AIGC 营销场景,且更贴近生产效果。我们开发了一个 Web 页面,可以端到端的理解每一个技术环节。

Web 首页展示效果

1. 整体架构介绍

首先我们介绍一下整个项目的模型调用架构。整个架构是基于 SageMaker 进行的模型环境部署,通常是把模型和推理代码上传到 S3 存储桶,也可以直接从 HuggingFace 直接下载。

架构图介绍

1.1 使用 SageMaker 的 Notebook 上传自定义代码到 S3 并完成部署,包含如下模型:

  • ChatGLM2 模型,使用了 SageMaker LMI 部署,模型从 HuggingFace 下载
  • Product Design Model(minimalism-eddiemauro),使用了 SageMaker LMI 部署,模型从 S3 存储桶下载
  • Segment Anything Model(SAM),使用 SageMaker 的 PyTorch 模型部署,模型从 S3 存储桶下载
  • Stable Diffusion 2 Inpaiting Model,使用了 SageMaker LMI 部署,模型从 HuggingFace 下载

1.2 使用 Bedrock 托管的基础模型,完成创意文案和创意图片生成等工作

只需通过相应的 SDK 进行 Bedrock 的调用,即可实现业务需求。

  • 调用 Bedrock Claude2,Titan,Llama2 皆可实现创意文案生成。
  • 调用 Bedrock Stable Diffusion 可以完成创意图片生成。

2. 营销文案页

在 Web 端,根据需求,提供商品描述,以及文案风格。会生成相应的文案。更详细的提示词(Prompt)会获取更准确的文案内容。

我们以一个帐篷为例来测试营销文案的撰写。

  • 商品描述(提示词)

驴友牌,帐篷,颜色鲜艳,轻便,抗风,抗雨,高山帐,海拔 5000 米

  • 风格选择:小红书

经过后台转换,提交给模型的提示词为:

请根据下面的内容写一段小红书的种草文案: 驴友牌,帐篷,颜色鲜艳,轻便,抗风,抗雨,高山帐,海拔 5000 米

  • 生成文案结果为:

驴友牌帐篷,绝对是户外探险的必备神器!这款帐篷具有鲜艳的颜色,轻便且抗风抗雨,非常适合在高山帐中使用。帐篷的尺寸适中,既可以容纳两个人,也可以容纳多人,非常适合团队出行。帐篷还带有通风口和透气窗,让您的睡眠更加舒适。帐篷还具有高山帐的特点,海拔 5000 米的高山气候恶劣,但驴友牌的帐篷可以抵御风雨,让您安心入睡。驴友牌帐篷是一款高品质的户外产品,具有出色的性能和实用性。如果您正在寻找一款高品质的帐篷,不妨考虑一下驴友牌,相信您一定不会失望!

  • 多轮对话
  • -如果希望对生成结果再加工,可以继续在商品描述中继续输入提示词:

突出可以在喜马拉雅山使用

  • -由于是多轮对话,后台提交无需对提示词进行继续加工,直接提交整个对话历史,此时生成文案结果为:

喜马拉雅山脉的顶峰,驴友牌帐篷助您轻松应对各种恶劣天气!这款帐篷具有鲜艳的颜色,轻便且抗风抗雨,非常适合在高山帐中使用。 帐篷的尺寸适中,既可以容纳两个人,也可以容纳多人,非常适合团队出行。帐篷还带有通风口和透气窗,让您的睡眠更加舒适。驴友牌帐篷还具有高山帐的特点,在海拔 5000 米的高山气候恶劣的情况下,驴友牌的帐篷可以抵御风雨,让您安心入睡。驴友牌帐篷是一款高品质的户外产品,具有出色的性能和实用性。作为您喜马拉雅山之旅的伙伴,驴友牌帐篷助您轻松应对各种恶劣天气,让您的探险之旅更加难忘!

您还继续输入,让 AI 继续写出您满意的内容。

2.1 大模型推理镜像 LMI

Large Model Inference(LMI)是用于大模型推理优化的镜像,该镜像包含了以下特性:

  • 通过 DJL Serving(基于 java 开发的高性能后端框架)暴露 HTTP 模型终端节点
  • 包含多种大模型推理优化引擎(DeepSpeed inference,FasterTransformer,Hugging Face Accelerate 等),从而降低延迟,提升吞吐
  • Tensor Parallel,支持将大模型拆分到多张 GPU 卡上实现推理过程的模型并行
  • 支持模型量化(GPTQ,Smoothquant 等),Attention 层计算优化如 Flash Attention 和 Paged Attention 等特性
  • 推理支持流式输出
  • 内置 s5cmd 高性能 S3 传输工具,从而实现大模型文件的快速下载

在 SageMaker 上使用 LMI 镜像非常简单,只需要提供 LMI 配置文件(serving.properties)与推理代码(model.py)即可。以下是示例代码:
serving.properties

engine=Python
option.tensor_parallel_degree=1
option.enable_streaming=True
option.predict_timeout=240
option.model_id=THUDM/chatglm2-6b

其中 engine 表示推理引擎,本示例中用的是 Hugging Face Accelerate,将 enging 指定为 Python 即可。
tensor_parallel_degree 表示 TP 并行度,本文使用一张 GPU 卡进行演示,因此将该参数设置为 1,实际参数需要根据业务需求进行评估。
enable_streaming 表示是否启用流式输出,可以将 token 以流式的方式返回给应用程序,提升用户体验。
model_id 指的是模型在 HuggingFace 上的 ID,部署时 LMI 会通过 model_id 下载模型。此外,若用户已将模型上传至 S3,则可以将 s3url 设置为模型所在的路径,LMI 会使用 s5cmd 直接将 S3 上的模型下载至容器环境。更多可配置参数和示例可以参考文档

model.py

from djl_python import Input, Output
import os
import torch
from transformers import AutoTokenizer, AutoModel
from typing import Any, Dict, Tuple
import warnings
import json

model = None
tokenizer = None

def get_model(properties):
    model_name = properties["model_id"]
    local_rank = int(os.getenv("LOCAL_RANK", "0"))
    model = AutoModel.from_pretrained(model_name, trust_remote_code=True).half().cuda()
    tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
    return model, tokenizer

def handle(inputs: Input) -> None:
    global model, tokenizer
    print("print inputs: " + str(inputs) + '.'*20)
    if not model:
        model, tokenizer = get_model(inputs.get_properties())

    if inputs.is_empty():
        # Model server makes an empty call to warmup the model on startup
        return None
    input_map = inputs.get_as_json()
    data = input_map.pop("inputs", input_map)
    parameters = input_map.pop("parameters", {})
    model = model.eval()
    response, history = model.chat(tokenizer, data, **parameters)
    out = {'response': response, 'history': history}
    return Output().add(json.dumps(out))

在 model.py 中,用户需要实现模型加载和推理的逻辑。get_model 函数会从 serving.properties 中拿到 model_id,然后加载模型。handel 函数用于解析应用程序调用模型服务器的输入,执行完推理后,以 json 的方式输出回应用程序。我们可以观察到,其中模型加载,推理用到的类,方法和本地使用 ChatGLM 是一致的,区别主要体现在 Input 和 Output 部分,这是 Model Server 对于输入输出的要求,我们按照这种规范进行编程即可。但在 serving.properties 中,我们用到了流式输出,对于如何处理流式 token 和本示例还有稍许不同,用户可以在 Github 上查看完整的代码逻辑。

2.2 营销文案架构图详解

  • 用户通过 Web 页面操作,向后端发出请求。
  • 服务端将用户输入转化为特定的 Prompt 提示词。
  • SageMaker 接收到输入参数,并把推理结果以流式进行输出。
  • 服务端通将输出流封装为 WebSocket 协议并返回给用户(前端)。

2.3 营销文案服务层源码解析

为了调用推理引擎,本方案使用了 Boto3 SDK,加入了中间服务层。在这个中间层,可以加入预处理环节,并且可以将流程串联起来。

另外通过加入 Streaming 方式的调用,提升了用户体验。最新版的 SDK 均已经集成了 Streaming 调用。

使用 invoke_model_with_response_stream 方法可以实现 Streaming 调用,如下代码:

smr = boto3.client("sagemaker-runtime")

async def ask_chatglm2(websocket: WebSocket, prompt: str, history):
    parameters = {"max_length": 4092, "temperature": 0.01, "top_p": 0.8}

    response_model = smr.invoke_endpoint_with_response_stream(
        EndpointName="chatglm2-lmi-model",
        Body=json.dumps(
            {"inputs": prompt, "parameters": parameters, "history": history}
        ),
        ContentType="application/json",
    )
    stream = response_model.get("Body")
    if stream:
        chunk_str_full = ""
        for event in stream:
            chunk = event.get("PayloadPart")
            if chunk:
                chunk_str_full = chunk_str_full + chunk.get("Bytes").decode()
                if chunk_str_full.strip().endswith(
                    "]}}"
                ) and chunk_str_full.strip().startswith("{"):
                    chunk_obj = json.loads(chunk_str_full)
                    result = chunk_obj["outputs"]["outputs"]
                    chunk_str_full = ""
                    await websocket.send_text(result)

    result_end = '{"status": "done"}'
    await websocket.send_text(result_end)

上述代码中:

  • 使用 sagemaker-runtime 的 invoke_endpoint_with_response_stream 实现了流式调用。
  • 拿到流式输出之后,通过解析出结果,并且通过 websocket 输出给前端。
  • 由于 ChatGLM 的一次输出结果太长,通常会把 JSON 字符串截断,所以需要找到 ]}} 作为一行的结尾。
  • 整体输出完成之后,输出一个 {"status": "done"} 作为结束,方便前端处理。

3. 创意设计页

创意设计页,可以根据输入的提示词,生成相应的图片。也可以通过上传图片的方式,以图生图。更准确的提示词和反相提示词,生成的图片会更贴近你的构想设计。

例: 输入“帐篷”,及相关反向提示词(默认已经提供部分常用反向提示词)

即可获得一个帐篷设计图,我们也可以选择图片数量,在生成的图片中,选择最贴近设计思路的一个图片。

3.1 创意设计架构图详解

  • 用户通过 Web 页面操作,向后端发出请求,包含正向提示词,反向提示词等内容。
  • 服务端调用 Amazon Translate 服务将用户输入的非英语的文本翻译为英文。
  • Amazon Translate 返回翻译后的英文文本。
  • 处理输入参数,调用 SageMaker 进行推理。
  • 返回推理等结果,即生成的图片。
  • 显示给前端 Web 页面。

3.2 创意设计中应用层源码解析

本方案通过 SageMaker 的 SDK 进行调用(也可以通过 Boto3 进行调用)。

在图片输出场景下,SageMaker 的输出结果通常会封装成 base64 字符串进行输出,下面的代码获取了输出结果,直接输出到前端。

{
from utils.aws import translate
from sagemaker import Predictor, serializers, deserializers

class Paint:
    def __init__(self):
        self.pd_predictor = Predictor(
            endpoint_name="product-design-sd",
            serializer=serializers.JSONSerializer(),
            deserializer=deserializers.JSONDeserializer(),
        )

    def product_design(self, item: dict):
        height = get_int(item, "height", 512)
        width = get_int(item, "width", 512)

        if height % 8 != 0 or width % 8 != 0:
            return {"error": "height or width must be multiple of 8"}
        if height > 1024 or width > 1024:
            return {"error": "height or width must be less than 1024"}

        prompt = translate(get_str(item, "prompt", None))

        negative_prompt = get_str(item, "negative_prompt", None)

        if negative_prompt:
            negative_prompt = translate(negative_prompt)
        else:
            negative_prompt = "low quantity"

        steps = get_int(item, "steps", 30)
        seed = get_int(item, "seed", -1)
        count = get_int(item, "count", 1)

        item["prompt"] = prompt
        item["negative_prompt"] = negative_prompt
        item["steps"] = steps
        item["seed"] = seed
        item["height"] = height
        item["width"] = width
        item["count"] = count
        item["output_image_dir"] = f"s3://{self.s3_bucket}/product-images/"

        return self.pd_predictor.predict(item)
}

上述代码中:

  • 通过 SageMaker SDK 进行调用推理。
  • 前端可以指定图片尺寸,在 Stable Diffusion 中,此尺寸需要是 8 的倍数,也不能太大,过大的尺寸会输出奇怪的图片,并且显存会溢出。
  • Stable Diffusion 当前版本只支持英文,为了支持多语言,调用了一个 AWS translate 服务,可以将用户输入的语言翻译成英文。
  • 调用 SageMaker 推理后,直接将结果输出给前端。

SageMaker 推理端输出的是 PNG 的图片格式,前端只需要在 base64 的字符串前面加上 data:image/png;base64, 即可渲染图片。

下面的代码处理了前端的图片渲染:

<Image src={'data:image/png;base64,' + responseString} />

4. 背景变焕页

在背景变焕中,我们将现有的营销图片进行上传,并输入产品的描述(图片需要保留部分),和背景提示词(需要重新设计并更换的部分),准确的提示词,也是获得理想结果的必要条件。

例:上传一张赛车照片,输入产品描述“跑车”,背景提示词“乡村,公路,绿化”

根据“背景描述”,生成了更换过背景的跑车图片。

4.1 背景变焕模型介绍

背景变焕使用到了两个模型:Segment Anything Model(SAM)和 stable-diffusion-2-inpainting

4.1.1 Segment Anything Model(SAM)

分割一切模型,根据点或框等输入提示生成高质量的对象蒙版,并且可用于为图像中的所有对象生成蒙版。基于 1100 万张图像和 11 亿个掩模的数据集上进行训练,在各种分割任务上具有强大的零样本性能。

4.1.2 stable-diffusion-2-inpainting
  • 根据文本提示生成和修改图像
  • 基于 Stable Diffusion V2,遵循 https://github.com/advimman/lama 蒙版生成策略,额外训练 200k steps 得到的模型

通过这两个模型,实现了抠图(遮罩/蒙板),然后根据提示词更换背景的过程。原理如下图:

4.2 背景变焕架构图详解

  • 用户通过 Web 页面操作,向后端发出请求,包含正向提示词,反向提示词等内容。
    服务端调用 Amazon Translate 服务将用户输入的非英语的文本翻译为英文。
  • Amazon Translate 返回翻译后的英文文本。
  • 使用提示词(需要保留的内容)调用 SAM 模型进行图像分隔。
  • 模型将分隔的结果(蒙板图片)暂存到 S3,并将地址返回给应用服务端。
  • 输入原图片,蒙板图片以及提示词等参数,调用 SD Inpainting 模型进行图片的重新生成。
  • 图片返回给应用服务端。
  • 最终呈现给前端 Web 页面。

代码的编写于前述章节的类似。

5. 基于 Amazon Bedrock 的营销场景应用

在大模型快速发展的今天,越来越多优秀的公司提供了功能众多的模型。让使用者“应接不暇”的同时,也疲于开发和适配新的模型。作为以客户至上为导向的公司,亚马逊云科技也推出了自己的基础模型 Amazon Titan。在 Titan 之外,我们也将来自 AI21 Labs、Anthropic 和 Stability AI 等第三方的基础模型集成进来,通过 Bedrock 统一提供给大家。在保证客户数据私有化等同时,通过 Bedrock API 快捷高效的使用基础模型,完成应用的开发,而不需要管理基础设施,和担心数据安全。

接下来,我们详细介绍,如何在营销场景中,通过 Bedrock 来实现需求。

5.1 基于 Bedrock 的架构图详解

Bedrock 的推理非常简单,本质就是一个 API 调用的过程,如下架构图:

5.2 Bedrock 代码解析

Bedrock 已经部署了很多优秀的模型。我们只需要通过相应的 SDK 即可进行 Bedrock 的调用。

5.2.1 下面的代码演示了以流式调用 Bedrock 的 Claude2 语言模型:
{
  
bedrock = boto3.client(service_name="bedrock-runtime")

async def ask_bedrock_claude2(websocket: WebSocket, prompt: str, history):
    modelId = "anthropic.claude-v2"
    accept = "*/*"
    contentType = "application/json"
    body = json.dumps(
        {
            "prompt": claude2_combine_history(history, prompt),
            "max_tokens_to_sample": 2048,
            "temperature": 0.5,
            "top_p": 0.9,
        }
    )
    response = bedrock.invoke_model_with_response_stream(
        body=body,
        modelId=modelId,
        accept=accept,
        contentType=contentType,
    )
    stream = response.get("body")
    if stream:
        for event in stream:
            chunk = event.get("chunk")
            if chunk:
                chunk_obj = json.loads(chunk.get("bytes").decode())
                # print(chunk_obj)
                text = chunk_obj["completion"]
                await websocket.send_text(text)

        result_end = '{"status": "done"}'
        await websocket.send_text(result_end)
}
5.5.2 下面的代码演示了 Bedrock SDXL 的调用:
def bedrock_product_design(self, item: dict):
    height = get_int(item, "height", 512)
    width = get_int(item, "width", 512)

    if height != 512 and width != 512:
        return {"error": "height or width must be 512"}
    if height % 64 != 0 or width % 64 != 0:
        return {"error": "height or width must be multiple of 64"}
    if height > 1024 or width > 1024:
        return {"error": "height or width must be less than 1024"}

    steps = get_int(item, "steps", 30)
    count = get_int(item, "count", 1)

    prompt = translate(get_str(item, "prompt", None))

    negative_prompt = get_str(item, "negative_prompt", None)

    if negative_prompt:
        negative_prompt = translate(negative_prompt)

    style_preset = get_str(item, "style_preset", "3d-model")
    request = json.dumps(
        {
            "text_prompts": (
                [
                    {"text": prompt, "weight": 1.0},
                    {"text": negative_prompt, "weight": -1.0},
                ]
            ),
            "cfg_scale": 10,
            # "seed": -1,
            "steps": steps,
            "style_preset": style_preset,
            "width": width,
            "height": height,
            "count": count,
        }
    )
    modelId = "stability.stable-diffusion-xl"
    response = self.bedrock.invoke_model(body=request, modelId=modelId)
    response_body = json.loads(response.get("body").read())
    return {"images": [response_body["artifacts"][0].get("base64")]}

通过上面的两个代码示例,可以看出 bedrock 的调用特点:

  • 需要指定不同的 modelId,这个 modelId 对于每个模型和其版本 是固定的字符串。
  • 模型的调用方式是一致的,具体有两个方法: invoke_modelinvoke_model_with_response_stream,有些模型支持流式,有些不支持,具体可以参考文档。
  • 每个模型的入参不一样。
  • 每个模型的输出结果结构不一样。

总结

感谢你的时间,看到这里,相信你对于营销场景的 AIGC 应用,已经有了清晰的理解和认识。或许已经激发出你动手体验的想法。为了方便深入理解和体验,我们也构建了 Workshop。你可以花上 2 个小时,跟随 Workshop 的步骤,深度体验 AIGC 营销场景。相信你会有更深刻的体会——AIGC 挺简单的!

文末,我们也为你呈上了完整的代码,并为每一段代码提供详细注释,

Workshop – 构建端到端生成式 AI 应用

https://catalog.us-east-1.prod.workshops.aws/workshops/4aec1efd-5181-46be-b7b1-2ee9292dae80/zh-CN

源码下载链接

为了精简易读,本文只列出核心代码及讲解。如需要深入研究,可根据需要从 Github 下载,我们公开了全部的源代码(并持续迭代更新)。

  1. CloudFormation 部署脚本
    AWS 基础环境部署代码,包含开通 AWS 运行环境,部署应用测代码
    https://github.com/aws-east-ai/east-ai-deploy
  2. 生成式 AI 模型部署脚本
    基础模型部署,包含如下模型的部署:ChatGLM2,Stable Diffusion,SAM 等
    https://github.com/aws-east-ai/east-ai-models
  3. 前端应用 UI 代码
    使用 react 开发的前端应用
    https://github.com/aws-east-ai/east-ai-ui
  4. 应用服务端代码
    使用 Python 开发的应用服务端
    https://github.com/aws-east-ai/east-ai-backend
  5. 为了方便深入理解和体验,我们也构建了 Workshop。 根据 Workshop,可以自己动手,深度体验 AIGC 营销场景
    https://catalog.us-east-1.prod.workshops.aws/workshops/4aec1efd-5181-46be-b7b1-2ee9292dae80/zh-CN

参考文档

  1. Amazon SageMaker
  2. Amazon Translate
  3. AWS SDK for Python (Boto3)
  4. HuggingFace
  5. FastAPI
  6. ChatGLM2-6B
  7. Product Design Model
  8. Stable Diffusion 2 inpainting model
  9. Segment Anything (SAM)

本篇作者

许晓亮

亚马逊云科技解决方案架构师,负责基于 AWS 云计算方案架构的咨询和设计,在国内推广 AWS 云平台技术和各种解决方案。擅长数据库和大数据领域,结合云原生特性,为客户设计高效稳定的全球化系统方案。

谢正伟

亚马逊云科技资深解决方案架构师,致力于云计算方案架构设计、应用和推广。具有 20 多年 IT 行业工作经验,擅长应用的架构和开发,历任全栈开发工程师,应用架构师,系统架构师等。在加入 AWS 之前,曾服务于优酷,阿里巴巴,腾讯等公司。

肖元君

亚马逊云科技解决方案架构师,负责基于 AWS 云计算方案的架构咨询和设计实现,同时致力于数据分析与 AI 的研究与应用。

吴万涛

亚马逊云科技解决方案架构师,负责 AWS 云上解决方案架构设计和咨询,十几年 IT 行业从业经历,在网络、应用架构、容器等领域有丰富的经验。

梁风飚

亚马逊云科技解决方案架构师经理,服务华东地区独立软件开发商(ISV)和企业客户。有丰富的软件开发,IT 系统架构设计,产品及项目管理经验。