Приложение для генерации изображений без серверов с использованием генеративного искусственного интеллекта на платформе AWS

Приложение на основе AWS для генерации изображений без серверов с использованием генеративного искусственного интеллекта

Будь то создание персонализированного контента или настройка изображений под предпочтения пользователя, способность генерировать визуальные ресурсы на основе описания является довольно мощной. Однако преобразование текста в изображение обычно включает в себя развертывание полного решения машинного обучения, что требует больших ресурсов. А что, если эта возможность будет доступна через вызов API, что упростит процесс и обеспечит доступность для разработчиков?

В этом руководстве вы узнаете, как использовать AWS CDK для развертывания приложения по генерации изображений, реализованного с использованием AWS Lambda и Amazon Bedrock, что является полностью управляемой службой, которая предоставляет доступ к базовым моделям от Amazon и поставщикам сторонних моделей (таким как Anthropic, Cohere и другим) через API. Разработчики могут использовать ведущие базовые модели через единое API и при этом сохранять гибкость в принятии новых моделей в будущем.

Решение развертывается в виде статического веб-сайта, размещенного на Amazon S3 и доступного через домен Amazon CloudFront. Пользователи могут вводить описание изображения, которое будет передано в функцию Lambda (через Amazon API Gateway), которая в свою очередь будет вызывать модель Stable Diffusion на Amazon Bedrock для генерации изображения.

Вся реализация основана на Go – это включает в себя функцию Lambda (с использованием библиотеки aws-lambda-go) и полное развертывание решения с использованием AWS CDK.

Код доступен на GitHub.

Условия

Перед началом работы над этим руководством вам понадобятся следующие компоненты:

  • Учетная запись AWS (если у вас еще нет учетной записи, вы можете создать ее и настроить среду здесь)
  • Go (v1.19 или выше)
  • AWS CDK
  • AWS CLI
  • Git
  • Docker

Склонируйте этот репозиторий на GitHub и перейдите в соответствующий каталог:

git clone https://github.com/build-on-aws/amazon-bedrock-lambda-image-generation-golangcd amazon-bedrock-lambda-image-generation-golang

Развертывание решения с использованием AWS CDK

Для начала развертывания просто вызовите cdk deploy.

cd cdkexport DOCKER_DEFAULT_PLATFORM=linux/amd64cdk deploy

Вы увидите список создаваемых ресурсов и должны будете подтвердить свое намерение продолжить (вывод сокращен для краткости).

Пакетирование ресурса BedrockLambdaImgeGenWebsiteStack/bedrock-imagegen-s3/Code/Stage...✨ Время синтеза: 7.84сек//.... опущеноЭто развертывание может вносить потенциально чувствительные изменения в соответствии с вашим текущим уровнем разрешений безопасности (--require-approval broadening).Подтвердите, что вы хотите внести следующие изменения://.... опущеноВы хотите выполнить развертывание этих изменений (y/n)? y

Это начнет создание требуемых AWS-ресурсов для приложения.

Если вы хотите просмотреть шаблон AWS CloudFormation, который будет использован внутри, выполните команду cdk synth и проверьте папку cdk.out.

Вы можете отслеживать ход выполнения в терминале или перейти в AWS Console: CloudFormation > Stacks > BedrockLambdaImgeGenWebsiteStack.

После создания всех ресурсов вы можете попробовать приложение. У вас должно быть:

  • Функция Lambda и API Gateway для генерации изображений
  • Корзина S3 для размещения HTML-страницы веб-сайта
  • Распределение CloudFront
  • И несколько других компонентов (таких как роли IAM, разрешения, политика S3 Bucket и т. д.)

Установка может занять некоторое время, так как создание распределения CloudFront является трудоемким процессом. По завершении вы должны получить подтверждение вместе со значениями для имени корзины S3, URL-адреса API Gateway и доменного имени CloudFront.

Обновите HTML-страницу и скопируйте ее в корзину S3

Откройте файл index.html в репозитории GitHub и найдите следующий текст: ENTER_API_GATEWAY_URL. Замените его URL-адресом API Gateway, который вы получили в качестве вывода развертывания CDK выше.

Чтобы скопировать файл в S3, я использовал AWS CLI:

aws s3 cp index.html s3://<имя корзины S3 из вывода CDK>

Убедитесь, что файл был загружен:

aws s3 ls s3://<имя корзины S3 из вывода CDK>

Теперь вы готовы получить доступ к веб-сайту!

Проверьте решение

Введите доменное имя CloudFront в веб-браузере, чтобы перейти на веб-сайт. Вы должны увидеть веб-сайт с предварительно заполненным описанием, которое можно использовать в качестве подсказки.

Нажмите Сгенерировать изображение, чтобы начать процесс. Через несколько секунд вы должны увидеть сгенерированное изображение.

Измените параметры модели

Модель стабильного диффузионного процесса позволяет нам уточнить параметры генерации в соответствии с нашими требованиями.

Модели стабильного диффузионного процесса поддерживают следующие элементы управления:

  • Сила подсказки (cfg_scale) управляет точностью изображения по отношению к подсказке, с меньшими значениями увеличивается случайность.
  • Шаг генерации (steps) определяет точность результата, с большим количеством шагов получаются более точные изображения.
  • Начальное значение (seed) устанавливает начальный уровень шума, позволяя получать воспроизводимые результаты при использовании одинакового начального значения и настроек.

Нажмите Показать конфигурацию, чтобы отредактировать их.

Максимальные значения для cfg_steps и steps составляют 30 и 150 соответственно.

Не забудьте очистить

По завершении работы, чтобы удалить все службы, просто используйте:

cdk destroy#вывод подсказки (выберите 'y' для продолжения)Вы точно хотите удалить: BedrockLambdaImgeGenWebsiteStack (y/n)?

Вы смогли настроить и испытать полное решение. Прежде чем мы закончим, давайте быстро пройдемся по некоторым значимым частям кода, чтобы лучше понять, что происходит за кулисами.

Обзор кода

Поскольку мы сосредоточимся только на важных моментах, много кода (выводы на печать, обработка ошибок и т.д.) опущено для краткости.

CDK

Вы можете сослаться на код CDK здесь.

Мы начинаем с создания API Gateway и корзины S3.

    apigw := awscdkapigatewayv2alpha.NewHttpApi(stack, jsii.String("image-gen-http-api"), nil)    bucket := awss3.NewBucket(stack, jsii.String("website-s3-bucket"), &awss3.BucketProps{        BlockPublicAccess: awss3.BlockPublicAccess_BLOCK_ALL(),        RemovalPolicy:     awscdk.RemovalPolicy_DESTROY,        AutoDeleteObjects: jsii.Bool(true),    })

Затем мы создаем идентификатор доступа к источнику CloudFront и предоставляем разрешения на чтение корзины S3 для данного идентификатора доступа к источнику CloudFront:

  • Укажите корзину S3 в качестве источника.
  • Укажите идентификатор доступа к источнику CloudFront, который мы создали ранее.
    oai := awscloudfront.NewOriginAccessIdentity(stack, jsii.String("OAI"), nil)    bucket.GrantRead(oai.GrantPrincipal(), "*")    distribution := awscloudfront.NewDistribution(stack, jsii.String("MyDistribution"), &awscloudfront.DistributionProps{        DefaultBehavior: &awscloudfront.BehaviorOptions{            Origin: awscloudfrontorigins.NewS3Origin(bucket, &awscloudfrontorigins.S3OriginProps{                OriginAccessIdentity: oai,            }),        },        DefaultRootObject: jsii.String("index.html"), //имя файла в S3    })

Затем мы создаем функцию генерации изображений Lambda вместе с IAM-разрешениями (для роли IAM-выполнения функции), чтобы разрешить ей вызывать операции Bedrock.

    function := awscdklambdagoalpha.NewGoFunction(stack, jsii.String("bedrock-imagegen-s3"),        &awscdklambdagoalpha.GoFunctionProps{            Runtime: awslambda.Runtime_GO_1_X(),            Entry:   jsii.String(functionDir),            Timeout: awscdk.Duration_Seconds(jsii.Number(30)),        })    function.AddToRolePolicy(awsiam.NewPolicyStatement(&awsiam.PolicyStatementProps{        Actions:   jsii.Strings("bedrock:*"),        Effect:    awsiam.Effect_ALLOW,        Resources: jsii.Strings("*"),    }))

Наконец, мы настраиваем интеграцию функции Lambda с API Gateway, добавляем маршруты HTTP и указываем конечную точку API Gateway, имя сокета S3 и доменное имя CloudFront в качестве выходных данных CloudFormation.

    functionIntg := awscdkapigatewayv2integrationsalpha.NewHttpLambdaIntegration(jsii.String("function-integration"), function, nil)    apigw.AddRoutes(&awscdkapigatewayv2alpha.AddRoutesOptions{        Path:        jsii.String("/"),        Methods:     &[]awscdkapigatewayv2alpha.HttpMethod{awscdkapigatewayv2alpha.HttpMethod_POST},        Integration: functionIntg})    awscdk.NewCfnOutput(stack, jsii.String("apigw URL"), &awscdk.CfnOutputProps{Value: apigw.Url(), Description: jsii.String("API Gateway endpoint")})    awscdk.NewCfnOutput(stack, jsii.String("cloud front domain name"), &awscdk.CfnOutputProps{Value: distribution.DomainName(), Description: jsii.String("cloud front domain name")})    awscdk.NewCfnOutput(stack, jsii.String("s3 bucket name"), &awscdk.CfnOutputProps{Value: bucket.BucketName(), Description: jsii.String("s3 bucket name")})

Функция Lambda

Вы можете ознакомиться с кодом функции Lambda здесь.

В обработчике функции мы извлекаем подсказку из тела HTTP-запроса и конфигурацию из параметров запроса. Затем они используются для вызова модели с помощью функции bedrockruntime.InvokeModel. Обратите внимание, что JSON-пакет, отправленный в Amazon Bedrock, представлен экземпляром структуры Request.

Тело вывода, возвращенное моделью “Amazon Bedrock Stability Diffusion”, является JSON-пакетом, который преобразуется в структуру Response, содержащую сгенерированное изображение в виде строки base64. Это возвращается в виде объекта events.APIGatewayV2HTTPResponse вместе с заголовками CORS.

func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) {    prompt := req.Body    cfgScaleF, _ := strconv.ParseFloat(req.QueryStringParameters["cfg_scale"], 64)    seed, _ := strconv.Atoi(req.QueryStringParameters["seed"])    steps, _ := strconv.Atoi(req.QueryStringParameters["steps"])    payload := Request{        TextPrompts: []TextPrompt{{Text: prompt}},        CfgScale:    cfgScaleF,        Steps: steps,    }    if seed > 0 {        payload.Seed = seed    }    payloadBytes, err := json.Marshal(payload)    output, err := brc.InvokeModel(context.Background(), &bedrockruntime.InvokeModelInput{        Body:        payloadBytes,        ModelId:     aws.String(stableDiffusionXLModelID),        ContentType: aws.String("application/json"),    })    var resp Response    err = json.Unmarshal(output.Body, &resp)    image := resp.Artifacts[0].Base64    return events.APIGatewayV2HTTPResponse{        StatusCode:      http.StatusOK,        Body:            image,        IsBase64Encoded: false,        Headers: map[string]string{            "Access-Control-Allow-Origin":  "*",            "Access-Control-Allow-Methods": "POST,OPTIONS",        },    }, nil}//модель запроса/ответаtype Request struct {    TextPrompts []TextPrompt `json:"text_prompts"`    CfgScale    float64      `json:"cfg_scale"`    Steps       int          `json:"steps"`    Seed        int          `json:"seed"`}type TextPrompt struct {    Text string `json:"text"`}type Response struct {    Result    string     `json:"result"`    Artifacts []Artifact `json:"artifacts"`}type Artifact struct {    Base64       string `json:"base64"`    FinishReason string `json:"finishReason"`}

Заключение

В этом учебнике вы использовали AWS CDK для развертывания решения по безсерверному созданию изображений, реализованного с использованием Amazon Bedrock и AWS Lambda, и получили доступ к нему через статический веб-сайт на S3 с помощью домена CloudFront.

Если вас интересует вводное руководство по использованию AWS Go SDK и Amazon Bedrock Foundation Models (FMs), ознакомьтесь с этим блог-постом.

Счастливого развития!