Используйте Amazon SageMaker Studio для создания решения по ответам на вопросы RAG с использованием Llama 2, LangChain и Pinecone для быстрого экспериментирования.

Создание решения по ответам на вопросы RAG с использованием Amazon SageMaker Studio опыт быстрого экспериментирования с Llama 2, LangChain и Pinecone через облако

Retrieval Augmented Generation (RAG) позволяет предоставить большой языковой модели (LLM) доступ к данным из внешних источников знаний, таких как репозитории, базы данных и API, без необходимости донастраивать ее. При использовании генеративного искусственного интеллекта для ответов на вопросы, RAG позволяет LLM отвечать на вопросы с наиболее актуальной и релевантной информацией и, по желанию, указывать источники данных для проверки.

Типичное решение RAG для извлечения знаний из документов использует модель эмбеддингов для преобразования данных из источников знаний в эмбеддинги и хранит эти эмбеддинги в векторной базе данных. Когда пользователь задает вопрос, система ищет в векторной базе данных и извлекает документы, наиболее похожие на запрос пользователя. Затем она комбинирует извлеченные документы и запрос пользователя в увеличенное начало, которое отправляется LLM для генерации текста. В этой реализации используются две модели: модель эмбеддингов и LLM, генерирующий конечный ответ.

В этой статье мы покажем, как использовать Amazon SageMaker Studio для создания решения вопросно-ответной системы RAG.

Использование блокнотов для вопросно-ответных систем на основе RAG

Реализация RAG часто предполагает экспериментирование с различными моделями эмбеддингов, векторными базами данных, моделями генерации текста и запросами, а также отладку кода до достижения работающего прототипа. Amazon SageMaker предлагает управляемые блокноты Jupyter, оборудованные вычислительными устройствами GPU, что позволяет вам быстро экспериментировать на этапе разработки без необходимости запуска дополнительной инфраструктуры. Существует два варианта использования блокнотов в SageMaker. Первый вариант – быстрый запуск блокнотов, доступных через SageMaker Studio. В SageMaker Studio, среде разработки, специально созданной для ML, вы можете запускать блокноты на различных типах экземпляров с разными конфигурациями, сотрудничать с коллегами и получать доступ к дополнительным функциям, специально разработанным для машинного обучения (ML). Второй вариант – использование экземпляра блокнота SageMaker, который является полностью управляемым вычислительным устройством для ML, работающим с приложением Jupyter Notebook.

В этой статье мы представляем решение RAG, которое дополняет знания модели дополнительными данными из внешних источников знаний, чтобы предоставлять более точные ответы, специфичные для пользовательской сферы. Мы используем один блокнот SageMaker Studio, работающий на экземпляре ml.g5.2xlarge (1 A10G GPU) и Llama 2 7b chat hf, настроенную версию Llama 2 7b, оптимизированную для диалоговых случаев использования из Hugging Face Hub. Мы используем две статьи в блоге Amazon AWS Media & Entertainment в качестве образца внешних данных, которые мы преобразуем в эмбеддинги с помощью эмбеддингов BAAI/bge-small-en-v1.5. Мы храним эти эмбеддинги в Pinecone, векторной базе данных, предлагающей высокопроизводительный поиск и сопоставление схожести. Мы также обсуждаем, как перейти от экспериментирования в блокноте к развертыванию моделей на конечных точках SageMaker для получения реального вывода в режиме реального времени при завершении прототипирования. Тот же подход можно использовать с различными моделями и векторными базами данных.

Обзор решения

На следующей диаграмме представлена архитектура решения.

Реализация решения состоит из двух основных этапов: разработка решения с использованием блокнотов SageMaker Studio и развертывание моделей для вывода.

Разработка решения с использованием блокнотов SageMaker Studio

Выполните следующие шаги для начала разработки решения:

  1. Загрузите модель Llama-2 7b чата с Hugging Face Hub в блокноте.
  2. Создайте шаблон PromptTemplate с LangChain и используйте его для создания промптов для вашего случая использования.
  3. Для 1-2 примеров промптов добавьте соответствующий статический текст из внешних документов в контекст промпта и оцените, улучшается ли качество ответов.
  4. Предполагая, что качество улучшается, реализуйте рабочий процесс вопросно-ответной системы RAG:
    • Соберите внешние документы, которые могут помочь модели лучше отвечать на вопросы в вашем случае использования.
    • Загрузите модель векторизации BGE и используйте ее для генерации векторов этих документов.
    • Сохраните эти векторы в индексе Pinecone.
    • Когда пользователь задает вопрос, выполните поиск похожести в Pinecone и добавьте содержание из наиболее похожих документов в контекст промпта.

Выкатите модели в SageMaker для инференса в масштабе

Когда вы достигнете своих целей производительности, вы можете задеплоить модели в SageMaker для использования в генеративных приложениях искусственного интеллекта:

  1. Задеплойте модель Llama-2 7b чата на реальный SageMaker эндпоинт.
  2. Задеплойте модель векторизации BAAI/bge-small-en-v1.5 на реальный SageMaker эндпоинт.
  3. Используйте задеплоенные модели в ваших приложениях генеративного искусственного интеллекта для вопросно-ответной системы.

В следующих разделах мы расскажем вам о шагах для реализации этого решения в блокнотах SageMaker Studio.

Предварительные требования

Для выполнения шагов в этой статье вам понадобится учетная запись AWS и роль управления доступом и идентификацией AWS (IAM), разрешающая создание и доступ к ресурсам решения. Если вы новичок в AWS, ознакомьтесь с инструкцией Создание самостоятельной учетной записи AWS.

Для использования блокнотов SageMaker Studio в вашей учетной записи AWS вам необходима область видимости SageMaker с пользовательским профилем, у которого есть права на запуск приложения SageMaker Studio. Если вы новичок в SageMaker Studio, наиболее быстрый способ начать работу – это выполнить настройку приложения Quick Studio setup. Единственным щелчком мыши SageMaker создаст область SageMaker с предустановленными настройками, включая настройку пользовательского профиля, роли IAM, аутентификации IAM и открытого доступа к интернету. В блокноте для этой статьи предполагается использование экземпляра типа ml.g5.2xlarge. Чтобы проверить или увеличить вашу квоту, откройте консоль AWS Service Quotas, выберите AWS Services в панели навигации, выберите Amazon SageMaker и обратитесь к значению для приложений Studio KernelGateway, работающих на экземплярах типа ml.g5.2xlarge.

После подтверждения вашего предела квоты, вам нужно завершить зависимости для использования Llama 2 7b чата.

Лицензия Llama 2 7b chat доступна по лицензии Llama 2. Чтобы получить доступ к Llama 2 на Hugging Face, вам необходимо выполнить несколько шагов:

  1. Создайте учетную запись Hugging Face, если у вас ее еще нет.
  2. Заполните форму “Запрос доступа к следующей версии Llama” на сайте Meta website.
  3. Запросите доступ к Llama 2 7b chat на Hugging Face.

После получения доступа вы можете создать новый токен доступа для доступа к моделям. Чтобы создать токен доступа, перейдите на страницу Настройки на сайте Hugging Face.

Чтобы использовать Pinecone в качестве векторной базы данных, вам необходимо иметь учетную запись с Pinecone. Pinecone доступен на AWS через AWS Marketplace. На сайте Pinecone также есть возможность создать бесплатную учетную запись, которая позволяет создавать один индекс, что достаточно для целей данной публикации. Чтобы получить свои ключи Pinecone, откройте консоль Pinecone и выберите API Keys.

Установка блокнота и окружения

Чтобы следовать коду в этой публикации, откройте SageMaker Studio и склонируйте репозиторий GitHub. Затем откройте блокнот studio-local-gen-ai/rag/RAG-with-Llama-2-on-Studio.ipynb и выберите образ PyTorch 2.0.0 Python 3.10 GPU Optimized, ядро Python 3 и ml.g5.2xlarge в качестве типа экземпляра. Если вы впервые используете блокноты SageMaker Studio, обратитесь к Создание или открытие блокнота Amazon SageMaker Studio.

Для настройки среды разработки вам необходимо установить необходимые библиотеки Python, как показано в следующем коде:

%%writefile requirements.txtsagemaker>=2.175.0transformers==4.33.0accelerate==0.21.0datasets==2.13.0langchain==0.0.297pypdf>=3.16.3pinecone-clientsentence_transformerssafetensors>=0.3.3

!pip install -U -r requirements.txt

Загрузка ранее обученной модели и токенизатора

После импорта необходимых библиотек вы можете загрузить модель Llama-2 7b chat вместе с соответствующими токенизаторами из Hugging Face. Эти загруженные артефакты модели хранятся в локальном каталоге в SageMaker Studio. Это позволяет вам быстро загрузить их в память всякий раз, когда вам нужно возобновить работу в другое время.

import torchfrom transformers import ( AutoTokenizer,  LlamaTokenizer, LlamaForCausalLM,   GenerationConfig,   AutoModelForCausalLM)import transformerstg_model_id = "meta-llama/Llama-2-7b-chat-hf" #the model id in Hugging Facetg_model_path = f"./tg_model/{tg_model_id}" #the local directory where the model will be savedtg_model = AutoModelForCausalLM.from_pretrained(tg_model_id, token=hf_access_token,do_sample=True, use_safetensors=True, device_map="auto", torch_dtype=torch.float16tg_tokenizer = AutoTokenizer.from_pretrained(tg_model_id, token=hf_access_token)tg_model.save_pretrained(save_directory=tg_model_path, from_pt=True)tg_tokenizer.save_pretrained(save_directory=tg_model_path, from_pt=True)

Задайте вопрос, требующий актуальной информации

Теперь вы можете начать использовать модель и задавать вопросы. Модели чата Llama-2 ожидают, чтобы промпт соответствовал следующему формату:

<s>[INST] <<SYS>>system_prompt<<SYS>>{{ user_message }} [/INST]

Вы можете использовать PromptTemplate из LangChain для создания шаблона на основе формата промпта, чтобы легко создавать промпты в будущем:

from langchain import PromptTemplatetemplate = """<s>[INST] <<SYS>>\nВы — помощник для задач по вопросам и ответам. Вы отзывчивы и дружелюбны. Чтобы ответить на запрос, используйте следующие фрагменты извлеченного контекста. Если вы не знаете ответ, просто скажите "Не знаю". Используйте максимум три предложения и делайте ответ лаконичным.<<SYS>>\n{context}\n{question} [/INST]"""prompt_template = PromptTemplate( template=template, input_variables=['context','question'] )

Давайте зададим модели вопрос, требующий актуальной информации из 2023 года. Вы можете использовать LangChain и конкретно тип цепи LLMChain, передавая в качестве параметров LLM, ранее созданный вами шаблон промпта и вопрос:

question = "Когда я смогу посетить Центр опыта клиентов AWS M&E в Нью-Йорке?"tg_tokenizer.add_special_tokens( {"pad_token": "[PAD]"} )tg_tokenizer.padding_side = "left"tg_pipe = transformers.pipeline(task='text-generation', model=tg_model, tokenizer=tg_tokenizer, num_return_sequences=1, eos_token_id=tg_tokenizer.eos_token_id, pad_token_id=tg_tokenizer.eos_token_id, max_new_tokens=400, temperature=0.7)from langchain.chains import LLMChainfrom langchain.llms import HuggingFacePipelinellm=HuggingFacePipeline(pipeline=tg_pipe, model_kwargs={'temperature':0.7})llm_chain = LLMChain(llm=llm, prompt=prompt_template)no_context_response = llm_chain.predict(context="", question=question)print(no_context_response)

Мы получаем следующий сгенерированный ответ:

Спасибо за обращение! Центр опыта клиентов AWS M&E в Нью-Йорке в настоящее время закрыт для посещений из-за пандемии COVID-19. Тем не менее, вы можете проверить их официальный веб-сайт или аккаунты в социальных сетях, чтобы узнать о любых обновлениях о дате открытия центра. В то время как вы можете осмотреть их виртуальные туры и доступные онлайн ресурсы.

Улучшите ответ, добавив контекст к промпту

Ответ, который мы сгенерировали, не полностью соответствует действительности. Давайте посмотрим, можем ли мы улучшить его, добавив некоторый контекст. Вы можете добавить отрывок из статьи AWS анонсирует новый Центр опыта клиентов M&E в Нью-Йорке, который включает обновления по данной теме из 2023 года:

context = """Клиентам средств массовой информации и развлечений (M&E) по-прежнему приходится сталкиваться с проблемами, связанными с созданием большего количества контента, более быстрого распространения его на большее количество платформ, чем когда-либо раньше, для радости зрителей по всему миру. Amazon Web Services (AWS), вместе с партнерами AWS, демонстрируют быстрое развитие решений для M&E уже много лет на отраслевых мероприятиях, таких как National Association of Broadcasters (NAB) Show и International Broadcast Convention (IBC). До сих пор технологические демонстрации по M&E от AWS были доступны только несколько недель в году. Клиенты теперь более активно участвуют и хотят проводить более качественные разговоры о пользовательском опыте и инструментах массовой информации. К таким разговорам лучше всего подходит использование связанной архитектуры решения в качестве справочного материала. Возможность запланировать визит в Центр опыта клиентов M&E станет доступна с 13 ноября, отправьте электронное письмо на адрес AWS-MediaEnt-CXC@amazon.com."""

Используйте снова LLMChain и передайте предыдущий текст в качестве контекста:

context_response = llm_chain.predict(context=context, question=question)print(context_response)

Новый ответ содержит актуальную информацию на вопрос:

Вы можете посетить Центр клиентского опыта AWS M&E в Нью-Йорке с 13 ноября. Пожалуйста, отправьте электронное письмо на адрес AWS-MediaEnt-CXC@amazon.com, чтобы назначить визит.

Мы подтверждаем, что добавление правильного контекста улучшает работу модели. Теперь вы можете сосредоточить свои усилия на нахождении и добавлении правильного контекста для заданного вопроса. Другими словами, внедрите RAG.

Внедрение модели RAG для ответа на вопросы с использованием вложений BGE и Pinecone

На этом этапе вам нужно определить источники информации для расширения знаний модели. Это могут быть внутренние веб-страницы или документы в вашей организации, а также общедоступные источники данных. В данной статье мы выбрали две статьи блога AWS, опубликованные в 2023 году:

Эти статьи уже доступны в виде PDF-документов в каталоге проекта данных в SageMaker Studio для быстрого доступа. Чтобы разделить документы на управляемые фрагменты, вы можете использовать метод RecursiveCharacterTextSplitter из LangChain:

from langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain.document_loaders import PyPDFDirectoryLoaderloader = PyPDFDirectoryLoader("./data/")documents = loader.load()text_splitter=RecursiveCharacterTextSplitter(     chunk_size=1000,     chunk_overlap=5)docs = text_splitter.split_documents(documents)

Затем используйте модель вложений BGE bge-small-en, созданную Пекинской академией искусственного интеллекта (BAAI), доступную в Hugging Face, для генерации вложений этих фрагментов. Скачайте и сохраните модель в локальном каталоге Studio. Мы используем fp32, чтобы модель работала на процессоре экземпляра.

em_model_name = "BAAI/bge-small-en"em_model_path = f"./em-model"from transformers import AutoModel# Загрузите модель из HuggingFace Hubem_model = AutoModel.from_pretrained(em_model_name,torch_dtype=torch.float32)em_tokenizer = AutoTokenizer.from_pretrained(em_model_name,device="cuda")# Сохраните модель на дискem_tokenizer.save_pretrained(save_directory=f"{em_model_path}/model",from_pt=True)em_model.save_pretrained(save_directory=f"{em_model_path}/model",from_pt=True)em_model.eval()

Используйте следующий код для создания функции embedding_generator, которая принимает фрагменты документа в качестве входных данных и генерирует вложения с использованием модели BGE:

# Токенизируйте предложенияdef tokenize_text(_input, device):    return em_tokenizer(        [_input],         padding=True,         truncation=True,         return_tensors='pt'    ).to(device)# Запустите задачу внедрения как функцию с моделью и предложениями текста в качестве входных данныхdef embedding_generator(_input, normalize=True):    # Вычислите вложения токенов    with torch.no_grad():        embedded_output = em_model(            **tokenize_text(                _input,                 em_model.device            )        )        sentence_embeddings = embedded_output[0][:, 0]        # нормализуем вложения        if normalize:            sentence_embeddings = torch.nn.functional.normalize(                sentence_embeddings,                 p=2,                 dim=1            )        return sentence_embeddings[0, :].tolist()    sample_sentence_embedding = embedding_generator(docs[0].page_content)print(f"Размер вложения документа --->", len(sample_sentence_embedding))

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

Мы инициализируем клиент Pinecone python и создаем новый поисковый индекс векторов, используя длину вывода встроенной модели. Мы используем встроенный класс Pinecone в LangChain для загрузки векторов, созданных на предыдущем шаге. Он требует трех параметров: документы для загрузки, функцию для генерации векторов и имя индекса Pinecone.

import pineconepinecone.init(    api_key = os.environ["PINECONE_API_KEY"],    environment = os.environ["PINECONE_ENV"])#проверяем, существует ли индекс, если нет — создаем егоindex_name = "rag-index"if index_name not in pinecone.list_indexes():    pinecone.create_index(        name=index_name,        dimension=len(sample_sentence_embedding), ## 384 for bge-small-en         metric='cosine'    )#вставляем векторыfrom langchain.vectorstores import Pineconevector_store = Pinecone.from_documents(    docs,    embedding_generator,    index_name=index_name)

С загруженной моделью чат-бота Llama-2 7B в памяти и интегрированными векторами в индекс Pinecone, теперь вы можете объединить эти элементы для усовершенствования ответов Llama 2 в задаче ответов на вопросы. Для этого вы можете использовать модуль RetrievalQA из LangChain, который расширяет начальный запрос наиболее похожими документами из хранилища векторов. Установив параметр return_source_documents=True, вы получаете возможность просмотреть точные документы, использованные для генерации ответа как часть ответа, что позволяет вам проверить точность ответа.

from langchain.chains import RetrievalQAimport textwrap#вспомогательный метод для улучшения читабельности ответаdef print_response(llm_response):    temp = [textwrap.fill(line, width=100) for line in llm_response['result'].split('\n')]    response = '\n'.join(temp)    print(f"{llm_response['query']}\n \n{response}'\n \n Source Documents:")    for source in llm_response["source_documents"]:        print(source.metadata)llm_qa_chain = RetrievalQA.from_chain_type(    llm=llm, #the Llama-2 7b chat model    chain_type='stuff',    retriever=vector_store.as_retriever(search_kwargs={"k": 2}), # perform similarity search in Pinecone    return_source_documents=True, #show the documents that were used to answer the question    chain_type_kwargs={"prompt": prompt_template})print_response(llm_qa_chain(question))

Мы получаем следующий ответ:

Вопрос: Когда можно посетить Центр клиентского опыта AWS M&E в Нью-Йорке?

Ответ: Я с радостью помогу! Согласно контексту, Центр клиентского опыта M&E AWS в Нью-Йорке будет открыт для посещений с 13 ноября. Вы можете отправить электронное письмо на AWS-MediaEnt-CXC@amazon.com, чтобы назначить визит.’

Источники:

{‘page’: 4.0, ‘source’: ‘data/AWS announces new M&E Customer Experience Center in New York City _ AWS for M&E Blog.pdf’}

{‘page’: 2.0, ‘source’: ‘data/AWS announces new M&E Customer Experience Center in New York City _ AWS for M&E Blog.pdf’}

Попробуем другой вопрос:

question2=" How many awards have AWS Media Services won in 2023?"print_response(llm_qa_chain(question2))

Мы получаем следующий ответ:

Вопрос: Сколько наград получили службы медиа AWS в 2023 году?

Ответ: Согласно блог-посту, службы медиа AWS получили пять отраслевых наград в 2023 году.’

Источники:

{‘page’: 0.0, ‘source’: ‘data/AWS Media Services awarded industry accolades _ AWS for M&E Blog.pdf’}

{‘page’: 1.0, ‘source’: ‘data/AWS Media Services awarded industry accolades _ AWS for M&E Blog.pdf’}

После достижения достаточного уровня уверенности вы можете развернуть модели на конечные точки SageMaker для получения результатов в реальном времени. Эти конечные точки полностью управляемы и поддерживают автомасштабирование.

SageMaker предлагает использование контейнеров для развертывания моделей с помощью контейнеров Large Model Inference (LMIs). Эти контейнеры оснащены предустановленными библиотеками с открытым исходным кодом, такими как DeepSpeed, что облегчает реализацию техник, улучшающих производительность, например, параллельной обработки тензоров во время вывода. Кроме того, они используют DJLServing в качестве предварительно построенного интегрированного сервера моделей. DJLServing – это высокопроизводительное универсальное решение для обслуживания моделей, которое предлагает поддержку динамической пакетизации и автомасштабирования рабочих задач, что увеличивает пропускную способность.

В нашем подходе мы используем SageMaker LMI с DJLServing и DeepSpeed Inference для развертывания моделей Llama-2-chat 7b и BGE на конечных точках SageMaker, работающих на экземплярах ml.g5.2xlarge, что позволяет выполнять вывод в реальном времени. Если вы хотите следовать этим шагам самостоятельно, обратитесь к сопроводительному блокноту для получения подробных инструкций.

Для развертывания вам понадобятся два экземпляра ml.g5.2xlarge. Чтобы просмотреть или увеличить свою квоту, откройте консоль AWS Service Quotas, выберите AWS Services в боковой панели навигации, выберите Amazon SageMaker и обратитесь к значению для ml.g5.2xlarge для использования конечной точки.

Следующие шаги определяют процесс развертывания пользовательских моделей для рабочего процесса RAG на конечной точке SageMaker:

  • Разверните модель общения Llama-2 7b на конечной точке SageMaker в режиме реального времени, работающей на экземпляре ml.g5.2xlarge, для быстрой генерации текста.
  • Разверните модель вложений BAAI/bge-small-en-v1.5 на конечной точке SageMaker в режиме реального времени, работающей на экземпляре ml.g5.2xlarge. При желании вы также можете развернуть свою собственную вложенную модель.
  • Задайте вопрос и используйте RetrievalQA LangChain для расширения запроса с помощью наиболее похожих документов из Pinecone, на этот раз используя модель, развернутую на конечной точке SageMaker в режиме реального времени:
# преобразование вашей локальной LLM в SageMaker LLMllm_sm_ep = SagemakerEndpoint(    endpoint_name=tg_sm_model.endpoint_name, # <--- Имя конечной точки вашей модели text-gen    region_name=region,    model_kwargs={        "temperature": 0.05,         "max_new_tokens": 512    },    content_handler=content_handler,)llm_qa_smep_chain = RetrievalQA.from_chain_type(    llm=llm_sm_ep,  # <--- В этом использована модель SageMaker Endpoint для вывода    chain_type='stuff',    retriever=vector_store.as_retriever(search_kwargs={"k": 2}),    return_source_documents=True,    chain_type_kwargs={"prompt": prompt_template})
  • Используйте LangChain, чтобы убедиться, что конечная точка SageMaker с моделью вложений работает ожидаемым образом, чтобы она могла быть использована для дальнейшего внесения документов:
response_model = smr_client.invoke_endpoint(    EndpointName=em_sm_model.endpoint_name, <--- Имя конечной точки вашей модели вложений    Body=json.dumps({        "text": "This is a sample text"    }),    ContentType="application/json",)outputs = json.loads(response_model["Body"].read().decode("utf8"))['outputs']

Очистка

Выполните следующие действия для очистки ресурсов:

  • Когда вы закончите работу в своей записной книжке SageMaker Studio, убедитесь, что вы остановили экземпляр ml.g5.2xlarge, чтобы избежать дополнительных расходов, выбрав значок остановки. Вы также можете настроить скрипты конфигурации жизненного цикла, чтобы автоматически выключать ресурсы, когда они не используются.

  • Если вы развернули модели на конечных точках SageMaker, запустите следующий код в конце блокнота, чтобы удалить конечные точки:
#delete your text generation endpointsm_client.delete_endpoint(     EndpointName=tg_sm_model.endpoint_name)# delete your text embedding endpointsm_client.delete_endpoint(      EndpointName=em_sm_model.endpoint_name)
  • Наконец, выполните следующую строку, чтобы удалить индекс Pinecone:
pinecone.delete_index(index_name)

Заключение

Блокноты SageMaker предоставляют простой способ начать свой путь с Retrieval Augmented Generation. Они позволяют вам взаимодействовать с различными моделями, конфигурациями и вопросами без создания дополнительной инфраструктуры. В этой статье мы показали, как повысить производительность чата Llama 2 7b в случае использования ответов на вопросы с использованием модели встраивания BGE и Pinecone. Чтобы начать, запустите SageMaker Studio и выполните блокнот, доступный в следующем репозитории GitHub. Пожалуйста, поделитесь своими мыслями в комментариях!