diff --git a/README.md b/README.md index b8d8f6f..7b250cf 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ AWS で機械学習をはじめる方法を学ぶことができるリポジト * 画像のセグメンテーションや物体検知、自然言語処理のQAや要約など、個別具体的なタスクを SageMaker でどのように解けるか学ぶためのコンテンツ。 * `solutions` * 製造業での異常検知モニタリングやコールセンターの問合せ分析など、特定の業務プロセスを効率化/差別化したい方が、 SageMaker と他のサービスを組み合わせどのようにソリューションを構築できるか学ぶためのコンテンツ。 +* `bedrock` + * 生成 AI を使ったアプリケーション開発を検討されている方が、Amazon Bedrock を使って実現するための方法を学ぶためのコンテンツ。 ## :hamburger: AWSの機械学習サービス @@ -91,6 +93,14 @@ Amazon SageMaker で機械学習の構築、学習、デプロイをスケール * [Amazon SageMaker Processing と AWS Step Functions でモデルの学習・評価・更新プロセスを構築する](./sagemaker/mlops/step-functions-data-science-sdk/step_functions_mlworkflow_scikit_learn_data_processing_and_model_evaluation_with_experiments.ipynb) * [Amazon SageMaker Processing と AWS Step Functions でモデルの学習・評価・更新プロセスを構築する (Studio 版 )](./sagemaker/mlops/step-functions-data-science-sdk/studio_step_functions_mlworkflow_scikit_learn_data_processing_and_model_evaluation_with_experiments.ipynb) +### [Amazon Bedrock](https://aws.amazon.com/jp/bedrock/) +生成 AI を使ったアプリケーションを、構築・運用するための基盤となるサービス + +#### サンプル +| No | Title | Description | Content | +|:-------| :-----------| :---- | :---- | +| 1 | Amazon Bedrock Beginners Handson | Amazon Bedrock を初めて触る方向けに、質問回答や要約の作成など基盤モデルのユースケースをお試しいただけるような Notebook コンテンツを提供します。 | [![Jupyter Notebook](https://img.shields.io/badge/jupyter-%23FA0F00.svg?style=for-the-badge&logo=jupyter&logoColor=white)](./bedrock/bedrock-beginners-handson/README.md) + ### 🚚 ML Frameworks 機械学習フレームワークの実装を SageMaker へ移行する。 @@ -134,7 +144,8 @@ AWS で画像処理や自然言語処理などの機械学習のタスクを解 * [細胞診 (FNA) 結果からの乳がん診断](./tasks/tabular/classification/BreastCancerPrediction_R.ipynb) -#### 🤖 生成系 AI +#### 🤖 生成 AI + ##### `text-to-image` @@ -143,7 +154,7 @@ AWS で画像処理や自然言語処理などの機械学習のタスクを解 | [Stable Diffusion Web UI](./tasks/generative-ai/text-to-image/inference/stable-diffusion-webui/) | Stable Diffusion の GUI として人気の [AUTOMATIC1111/stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) を EC2 インスタンスに立てて利用できるようにする CloudFormation です。モデルのトレーニングに [bmaltais/kohya_ss](https://github.com/bmaltais/kohya_ss)、GUI ベースのファイル操作に [filebrowser/filebrowser](https://github.com/filebrowser/filebrowser) を立ち上げる構成も含まれています。SageMaker JumpStart を利用した Fine Tuning については [たった数枚の画像で Stable Diffusion をファインチューニングできる効率的な Amazon SageMaker JumpStart の使い方](https://aws.amazon.com/jp/blogs/news/machine-learning-inpaint-images-with-stable-diffusion-using-amazon-sagemaker-jumpstart/) をご参照ください。 | | [Inpainting](./tasks/generative-ai/text-to-image/inference/Transformers/StableDiffusionInpainting_Inference_with_ClipSeg.ipynb) | 画像の一部を生成した画像で差し替えるサンプルです。差し替える箇所 ( マスク ) の作成には [CLIPSeg](https://huggingface.co/docs/transformers/model_doc/clipseg) を使用しています。詳細は [Stable Diffusion で画像の部分的な差し替えを行う環境を、 Amazon SageMaker JumpStart で簡単に構築する](https://aws.amazon.com/jp/blogs/news/machine-learning-inpaint-images-with-stable-diffusion-using-amazon-sagemaker-jumpstart/) をご参照ください。| -#### `text-to-text` +##### `text-to-text` | サンプルコード | 詳細 | |:-------| :-----------| @@ -155,7 +166,7 @@ AWS で画像処理や自然言語処理などの機械学習のタスクを解 SageMaker と他のサービスを組み合わせ、業務プロセスの効率化や差別化を行うためのソリューションを格納/紹介します。 * [JP RAG SOLUTION](https://github.com/aws-samples/jp-rag-sample) - * カスタマーサポートなどで生成系 AI を利用する場合、自然な応答による顧客体験の改善が期待できるものの、誤った発言 ( ハルシネーション ) が発生する恐れがあります。生成元のドキュメントを指定することで誤った発言を抑止することができ、検索エンジンから生成系 AI にドキュメントを与え生成する仕組みを RAG と呼びます。本ソリューションでは、検索エンジンとして `Amazon Kendra` 、生成系 AI として `Anthropic Claude` / [`rinna/japanese-gpt-neox-3.6b-instruction-ppo`](https://huggingface.co/rinna/japanese-gpt-neox-3.6b-instruction-ppo) を用いて RAG を実現します。 + * カスタマーサポートなどで生成 AI を利用する場合、自然な応答による顧客体験の改善が期待できるものの、誤った発言 ( ハルシネーション ) が発生する恐れがあります。生成元のドキュメントを指定することで誤った発言を抑止することができ、検索エンジンから生成 AI にドキュメントを与え生成する仕組みを RAG と呼びます。本ソリューションでは、検索エンジンとして `Amazon Kendra` 、生成 AI として `Anthropic Claude` / [`rinna/japanese-gpt-neox-3.6b-instruction-ppo`](https://huggingface.co/rinna/japanese-gpt-neox-3.6b-instruction-ppo) を用いて RAG を実現します。 * 参考記事: [高精度な生成系 AI アプリケーションを Amazon Kendra、LangChain、大規模言語モデルを使って作る](https://aws.amazon.com/jp/blogs/news/quickly-build-high-accuracy-generative-ai-applications-on-enterprise-data-using-amazon-kendra-langchain-and-large-language-models/) * [コールセンターのリアルタイム会話分析](https://aws.amazon.com/jp/blogs/news/live-call-analytics-and-agent-assist-for-your-contact-center-with-amazon-language-ai-services/) * コールセンターで会話の文字起こし、翻訳、感情分析、会話内容の要約、オペレーターへのアドバイスをリアルタイムで行うソリューションです。文字起こしは `Amazon Transcribe` 、翻訳は `Amazon Translate` 、 感情分析は `Amazon Comprehend` 、 要約は `Amazon SageMaker` 、 アドバイスは `Amazon Lex` と `Amazon Kendra` で実装しています。 diff --git a/bedrock/bedrock-beginners-handson/README.md b/bedrock/bedrock-beginners-handson/README.md new file mode 100644 index 0000000..bc2cc77 --- /dev/null +++ b/bedrock/bedrock-beginners-handson/README.md @@ -0,0 +1,34 @@ +# bedrock-beginners-handson + +このリポジトリでは、Amazon Bedrock を初めて触る方向けに、Amazon Bedrock をお試しいただけるような Notebook コンテンツを提供します。 +以下の 3 つのコンテンツを提供予定です。 +なお、Amazon Bedrock を利用する際にはモデルの有効化手続きが必要になります。[Amazon Bedrock をセットアップする](https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/setting-up.html)の手順をもとにセットアップをお願いします。 + +## Chapter1: 基盤モデルの基本的な呼び出し +[![Jupyter Notebook](https://img.shields.io/badge/jupyter-%23FA0F00.svg?style=for-the-badge&logo=jupyter&logoColor=white)](./chapter1_introduction.ipynb) +このチャプターでは、Python SDK を用いて Amazon Bedrock 上の基盤モデルを呼び出す方法をご紹介します。 + +## Chapter2: プロンプトエンジニアリング (作成中) +このチャプターでは実際に基盤モデルを使って、会社の宣伝メールやスローガンを生成するような仕組みを作ります。 + +## Chapter3: RAG 入門 (作成中) +このチャプターでは、検索拡張生成(Retrieval Augmented Generation) の仕組みや実装方法をご紹介します。 + +# 始めるにあたっての準備 + +このハンズオンでは SageMaker Notebook Instance での実行を前提とします。 +ノートブックインスタンスに対して、Bedrock の呼び出しを許可するため、次のような Bedrock Full Access 権限を実行ロールに付与してください。 + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Statement1", + "Effect": "Allow", + "Action": "bedrock:*", + "Resource": "*" + } + ] +} +``` diff --git a/bedrock/bedrock-beginners-handson/chapter1_introduction.ipynb b/bedrock/bedrock-beginners-handson/chapter1_introduction.ipynb new file mode 100644 index 0000000..b70a470 --- /dev/null +++ b/bedrock/bedrock-beginners-handson/chapter1_introduction.ipynb @@ -0,0 +1,1334 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6fe0548d-28d1-4a6e-9c9c-45139b5be31e", + "metadata": { + "tags": [] + }, + "source": [ + "# Amazon Bedrock 入門 Workshop \n", + "# Chapter1: 基本的なモデル呼び出し\n", + "\n", + "この章では Amazon Bedrock 上の基盤モデルを呼び出すための基本的な方法を体験していただきます。 \n", + "なお、実行環境は SageMaker Notebook を前提にしているため、他の環境(ローカル PC や SageMaker Studio Notebook)で実行する場合は適宜追加モジュールのインストールや IAM の権限設定が必要になる可能性があります。" + ] + }, + { + "cell_type": "markdown", + "id": "96bc2b6f", + "metadata": {}, + "source": [ + "\n", + "## 目次\n", + "\n", + "- [事前準備](#事前準備)\n", + "- [Python SDK での Amazon Bedrock の利用](#python-sdk-での-amazon-bedrock-の利用)\n", + "- [テキスト生成モデルの利用](#テキスト生成モデルの利用)\n", + "- [様々な基盤モデルの利用](#様々な基盤モデルの利用)\n", + "- [まとめ](#まとめ)" + ] + }, + { + "cell_type": "markdown", + "id": "f4873f86", + "metadata": {}, + "source": [ + "## 事前準備" + ] + }, + { + "cell_type": "markdown", + "id": "ea88f423", + "metadata": {}, + "source": [ + "### Amazon Bedrock 上での基盤モデルの有効化\n", + "\n", + "初めて Amazon Bedrock を使われる場合、モデル有効化手続きが必要となります。[ドキュメントの手順](https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/model-access.html)を参考に有効化をお願いします。\n" + ] + }, + { + "cell_type": "markdown", + "id": "7c5e2e8a-b748-48cc-8172-f68b05826daa", + "metadata": { + "jp-MarkdownHeadingCollapsed": true, + "tags": [] + }, + "source": [ + "### 必要権限の付与\n", + "\n", + "強めの権限にはなりますが、本コンテンツを実行するのに必要な権限を付与するために、下記ポリシーを SageMaker Studio の実行ロールにアタッチします。 \n", + "\n", + "```json\n", + "{\n", + " \"Version\": \"2012-10-17\",\n", + " \"Statement\": [\n", + " {\n", + " \"Sid\": \"Statement1\",\n", + " \"Effect\": \"Allow\",\n", + " \"Action\": \"bedrock:*\",\n", + " \"Resource\": \"*\"\n", + " }\n", + " ]\n", + "}\n", + "```\n", + "\n", + "詳しくは[こちらのドキュメント](https://docs.aws.amazon.com/sagemaker/latest/dg/sagemaker-roles.html)を参照してください。\n" + ] + }, + { + "cell_type": "markdown", + "id": "71be6c96-19b4-4b31-8175-348f87581305", + "metadata": { + "tags": [] + }, + "source": [ + "### ライブラリの準備\n", + "以下のセルを実行して必要な ```boto3, awscli, botocore, langchain``` パッケージをインストールします" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a59b0b7d-4bfb-4b33-bd85-b4b3be40114b", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%pip install boto3 awscli botocore langchain" + ] + }, + { + "cell_type": "markdown", + "id": "984fd323-2638-4899-a548-543e22e75b12", + "metadata": { + "tags": [] + }, + "source": [ + "## Python SDK での Amazon Bedrock の利用" + ] + }, + { + "cell_type": "markdown", + "id": "08c6d071-8e69-4d71-9b12-ae9648a6e395", + "metadata": {}, + "source": [ + "Amazon Bedrock を呼び出すための boto3 client を作成します。 \n", + "クライアントには、Bedrock Cllent, Bedrock Runtime Client, Bedrock Agent Client, Bedrock Agent Runtime Client の 4 種類が存在します。 \n", + "特に、基盤モデルを利用する際に用いるのは、Bedrock Cllent, Bedrock Runtime Client の 2 つになります。\n", + "\n", + "[Bedrock Client](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock.html) が基盤モデル一覧の表示や、カスタマイズジョブの管理など、制御面を扱うクライアントになります。 \n", + "\n", + "[Bedrock Runtime Client](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock-runtime.html) は基盤モデルの呼び出しに利用するクライアントになります。\n", + "\n", + "それでは、早速 Bedrock Client を使って利用可能な基盤モデルの一覧を取得します。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c91b0d83-151e-43f4-b8cd-90ae6e317aab", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import boto3\n", + "import json\n", + "# bedrock client\n", + "bedrock_client = boto3.client(service_name='bedrock')\n", + "bedrock_runtime_client = boto3.client(service_name='bedrock-runtime')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "30cdf5b4-ae04-4fc2-b6fe-e049697bc75a", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# 利用可能な基盤モデル一覧の表示\n", + "response_json = bedrock_client.list_foundation_models()\n", + "\n", + "for models in response_json['modelSummaries']:\n", + " print(models['modelId'])" + ] + }, + { + "cell_type": "markdown", + "id": "4d220028", + "metadata": {}, + "source": [ + "## テキスト生成モデルの利用" + ] + }, + { + "cell_type": "markdown", + "id": "6d88d0ac", + "metadata": {}, + "source": [ + "続いて、Bedrock Runtime Client を使って基盤モデルを呼び出し、文章を生成します。 \n", + "invoke_model関数を使うことで、基盤モデルを呼び出すことができます。 \n", + "以下では、 Anthropic Claude Instant を使った例を示します。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0e8fcde3", + "metadata": {}, + "outputs": [], + "source": [ + "# 基盤モデルを同期的に呼び出して推論する (Anthropic claude-instant-v1 の場合)\n", + "\n", + "model_id = 'anthropic.claude-instant-v1'\n", + "system_prompt = \"あなたは生成AIのエージェントです。ユーザからの質問に丁寧に回答してください。\"\n", + "max_tokens = 1000\n", + "temperature = 0\n", + "\n", + "# ユーザからの指示を記述する\n", + "user_message = {\n", + " \"role\": \"user\",\n", + " \"content\": \"日本で一番高い山を教えてください\" \n", + " }\n", + "\n", + "body = json.dumps(\n", + " {\n", + " \"anthropic_version\": \"bedrock-2023-05-31\",\n", + " \"max_tokens\": max_tokens,\n", + " \"system\": system_prompt,\n", + " \"messages\": [user_message],\n", + " \"temperature\": temperature\n", + " } \n", + ") \n", + "\n", + "response = bedrock_runtime_client.invoke_model(body=body, modelId=model_id)\n", + "response_json = json.loads(response.get('body').read())\n", + "\n", + "# 回答の表示\n", + "print('#回答')\n", + "print(response_json['content'][0]['text'])" + ] + }, + { + "cell_type": "markdown", + "id": "53d1fd71", + "metadata": {}, + "source": [ + "また、基盤モデルはストリーム形式で呼び出すことも可能です" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "88e8fd0c", + "metadata": {}, + "outputs": [], + "source": [ + "# 基盤モデルの推論結果をストリーム形式で得る (Anthropic claude-instant-v1 の場合)\n", + "\n", + "model_id = 'anthropic.claude-instant-v1'\n", + "system_prompt = \"あなたは生成AIのエージェントです。ユーザからの質問に丁寧に回答してください。\"\n", + "max_tokens = 1000\n", + "temperature = 0\n", + "\n", + "# ユーザからの指示を記述する\n", + "user_message = {\n", + " \"role\": \"user\",\n", + " \"content\": \"日本で一番高い山を教えてください\" \n", + " }\n", + "\n", + "body = json.dumps(\n", + " {\n", + " \"anthropic_version\": \"bedrock-2023-05-31\",\n", + " \"max_tokens\": max_tokens,\n", + " \"system\": system_prompt,\n", + " \"messages\": [user_message],\n", + " \"temperature\": temperature\n", + " } \n", + ") \n", + "\n", + "response = bedrock_runtime_client.invoke_model_with_response_stream(body=body, modelId=model_id)\n", + "\n", + "# 結果を受け取った分から出力する \n", + "for body in response.get('body'):\n", + " response_json = json.loads(body['chunk']['bytes'].decode())\n", + "\n", + " if response_json['type'] == 'message_start': \n", + " print('#ストリーム開始')\n", + " continue\n", + " if response_json['type'] == 'message_stop': \n", + " print('\\n#ストリーム終了')\n", + " continue\n", + " if response_json['type'] == 'content_block_start':\n", + " continue\n", + " if response_json['type'] == 'content_block_stop':\n", + " continue\n", + " if response_json['type'] == 'content_block_delta':\n", + " print(response_json['delta']['text'], end='')\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "d3ba36d4", + "metadata": {}, + "source": [ + "### 画像を入力としたテキスト生成" + ] + }, + { + "cell_type": "markdown", + "id": "2a174242", + "metadata": {}, + "source": [ + "Claude 3モデルでは、画像を入力とした呼び出しにも対応しています。以下はマルチモーダル呼び出しを行うコードの例になります。 " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e898df50", + "metadata": {}, + "outputs": [], + "source": [ + "import base64\n", + "\n", + "# 画像を読み込みbase64形式にエンコードする。\n", + "img_path = 'sample.png'\n", + "\n", + "with open(img_path, \"rb\") as f:\n", + " img_data = f.read()\n", + " base64_data = base64.b64encode(img_data)\n", + " base64_str = base64_data.decode(\"utf-8\")\n", + "\n", + "# モデルへのプロンプト\n", + "model_id = 'anthropic.claude-3-sonnet-20240229-v1:0'\n", + "system_prompt = \"あなたは生成AIのエージェントです。ユーザからの質問に丁寧に回答してください。\"\n", + "max_tokens = 1000\n", + "temperature = 0\n", + "\n", + "# ユーザからの指示と画像の内容を記述する\n", + "user_message = {\n", + " \"role\": \"user\",\n", + " \"content\": [\n", + " {\n", + " \"type\": \"image\",\n", + " \"source\": {\n", + " \"type\": \"base64\",\n", + " \"media_type\": \"image/png\",\n", + " \"data\": base64_str\n", + " }\n", + " },\n", + " {\n", + " \"type\": \"text\",\n", + " \"text\": \"画像に写っているものを説明してください。\"\n", + " }\n", + " ]\n", + "}\n", + "\n", + "body = json.dumps(\n", + " {\n", + " \"anthropic_version\": \"bedrock-2023-05-31\",\n", + " \"max_tokens\": max_tokens,\n", + " \"system\": system_prompt,\n", + " \"messages\": [user_message]\n", + " } \n", + ") \n", + "\n", + "try:\n", + " # 基盤モデルの呼び出し\n", + " response = bedrock_runtime_client.invoke_model(body=body, modelId=model_id).get('body').read()\n", + " response_json = json.loads(response)\n", + "\n", + " # 回答の表示\n", + " print('#回答')\n", + " print(response_json['content'][0]['text'])\n", + "\n", + "except ClientError as err:\n", + " message=err.response[\"Error\"][\"Message\"]\n", + " logger.error(\"A client error occurred: %s\", message)\n", + " print(\"A client error occured: \" +\n", + " format(message))" + ] + }, + { + "cell_type": "markdown", + "id": "1b5d2bc6", + "metadata": {}, + "source": [ + "次に、マルチモーダルモデルをストリーム形式で呼び出します。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95d85f8a", + "metadata": {}, + "outputs": [], + "source": [ + "# 基盤モデルのマルチモーダルでの推論結果をストリーム形式で得る (Anthropic claude-instant-v1 の場合)\n", + "\n", + "# 画像を読み込みbase64形式にエンコードする。\n", + "img_path = 'sample.png'\n", + "\n", + "with open(img_path, \"rb\") as f:\n", + " img_data = f.read()\n", + " base64_data = base64.b64encode(img_data)\n", + " base64_str = base64_data.decode(\"utf-8\")\n", + "\n", + "model_id = 'anthropic.claude-3-sonnet-20240229-v1:0'\n", + "system_prompt = \"あなたは生成AIのエージェントです。ユーザからの質問に丁寧に回答してください。\"\n", + "max_tokens = 1000\n", + "temperature = 0\n", + "\n", + "# ユーザからの指示と画像を記述する\n", + "user_message = {\n", + " \"role\": \"user\",\n", + " \"content\": [\n", + " {\n", + " \"type\": \"image\",\n", + " \"source\": {\n", + " \"type\": \"base64\",\n", + " \"media_type\": \"image/png\",\n", + " \"data\": base64_str\n", + " }\n", + " },\n", + " {\n", + " \"type\": \"text\",\n", + " \"text\": \"画像に写っているものを説明してください。\"\n", + " }\n", + " ]\n", + "}\n", + "\n", + "body = json.dumps(\n", + " {\n", + " \"anthropic_version\": \"bedrock-2023-05-31\",\n", + " \"max_tokens\": max_tokens,\n", + " \"system\": system_prompt,\n", + " \"messages\": [user_message],\n", + " \"temperature\": temperature\n", + " } \n", + ") \n", + "\n", + "response = bedrock_runtime_client.invoke_model_with_response_stream(body=body, modelId=model_id)\n", + "\n", + "# 結果を受け取った分から出力する \n", + "for body in response.get('body'):\n", + " response_json = json.loads(body['chunk']['bytes'].decode())\n", + "\n", + " if response_json['type'] == 'message_start': \n", + " print('#ストリーム開始')\n", + " continue\n", + " if response_json['type'] == 'message_stop': \n", + " print('\\n#ストリーム終了')\n", + " continue\n", + " if response_json['type'] == 'content_block_start':\n", + " continue\n", + " if response_json['type'] == 'content_block_stop':\n", + " continue\n", + " if response_json['type'] == 'content_block_delta':\n", + " print(response_json['delta']['text'], end='')" + ] + }, + { + "cell_type": "markdown", + "id": "f7f7d84b-084c-4aa7-80fc-37943d583496", + "metadata": { + "tags": [] + }, + "source": [ + "## 様々な基盤モデルの利用" + ] + }, + { + "cell_type": "markdown", + "id": "8fe08d68-b145-48d5-8b5c-2ab556f1f74b", + "metadata": {}, + "source": [ + "Bedrock では、テキスト生成に限らず、画像生成や埋め込み表現生成が可能です。\n", + "\n", + "2024/3/15 現在、オレゴン・バージニア北部リージョンにおいて以下のモデルが呼び出し可能です。 \n", + "\n", + "テキスト生成\n", + "\n", + "- AI21 Labs: Jurassic-2 Mid\n", + "- AI21 Labs: Jurassic-2 Ultra\n", + "- Amazon: Titan Text G1 - Lite\n", + "- Amazon: Titan Text G1 - Express\n", + "- Anthropic: Claude 2\n", + "- Anthropic: Claude 2.1\n", + "- Anthropic: Claude 3 Sonnet\n", + "- Anthropic: Claude 3 Haiku\n", + "- Anthropic: Claude Instant\n", + "- Cohere: Command\n", + "- Cohere: Command Light\n", + "- Meta: Llama 2 Chat 13B\n", + "- Meta: Llama 2 Chat 70B\n", + "- Mistral AI: Mistral 7B Instruct\n", + "- Mistral AI: Mixtral 8x7B Instruct\n", + "\n", + "画像からのテキスト生成\n", + "\n", + "- Anthropic: Claude 3 Sonnet\n", + "- Anthropic: Claude 3 Haiku\n", + "\n", + "画像生成\n", + "\n", + "- Amazon: Titan Image Generator G1\n", + "- Stability AI: StableDiffusion XL 1.0\n", + "- Stability AI: StableDiffusion XL 0.8 (Deprecated)\n", + "\n", + "埋め込み表現生成\n", + "\n", + "- Amazon: Titan Embeddings G1 - Text\n", + "- Amazon: Titan Multimodal Embeddings G1 \n", + "- Cohere: Embed English\n", + "- Cohere: Embed Multilingual\n", + "\n", + "\n", + "以下では、画像生成モデルや埋め込み表現生成モデルを使った実行例を示します。" + ] + }, + { + "cell_type": "markdown", + "id": "2443987e-c7d2-4e60-bdb3-e2f60bae6834", + "metadata": {}, + "source": [ + "### 画像生成モデルの呼び出し \n", + "実行する際はコメントアウトを外してください(行頭と行末の`'''`を外してください)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e41e7d20-6b14-449b-adfd-7925deabe14a", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import base64\n", + "import io\n", + "from PIL import Image\n", + "from IPython.display import display\n", + "import botocore" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "175043c9-e8bb-46cb-ac33-4f7eea1e5b21", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "'''\n", + "# SDXLモデルは 2024/2/6 現在バージニア北部リージョンとオレゴンリージョンにのみ存在するため、別でクライアントを定義します\n", + "bedrock_sdxl_client = boto3.client(service_name='bedrock-runtime', region_name='us-east-1')\n", + "\n", + "prompt_data = \"a fine image of an astronaut riding a horse on Mars\"\n", + "body = json.dumps({\n", + " \"text_prompts\": [{\"text\": prompt_data}],\n", + " \"cfg_scale\": 10,\n", + " \"seed\": 20,\n", + " \"steps\": 50\n", + "})\n", + "modelId = \"stability.stable-diffusion-xl\"\n", + "accept = \"application/json\"\n", + "contentType = \"application/json\"\n", + "\n", + "try:\n", + " \n", + " response = bedrock_sdxl_client.invoke_model(\n", + " body=body, modelId=modelId, accept=accept, contentType=contentType\n", + " )\n", + " response_body = json.loads(response.get(\"body\").read())\n", + " \n", + " print(response_body[\"result\"])\n", + " print(f'{response_body.get(\"artifacts\")[0].get(\"base64\")[0:80]}...')\n", + "\n", + "except botocore.exceptions.ClientError as error:\n", + " \n", + " if error.response['Error']['Code'] == 'AccessDeniedException':\n", + " print(f\"\\x1b[41m{error.response['Error']['Message']}\\\n", + " \\nTo troubeshoot this issue please refer to the following resources.\\\n", + " \\nhttps://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_access-denied.html\\\n", + " \\nhttps://docs.aws.amazon.com/bedrock/latest/userguide/security-iam.html\\x1b[0m\\n\")\n", + " \n", + " else:\n", + " raise error\n", + "\n", + "'''" + ] + }, + { + "cell_type": "markdown", + "id": "bf094dc8-2605-4497-9171-a548a20dd7a5", + "metadata": {}, + "source": [ + "出力結果は base64 でエンコードされているため、デコードしてから表示します。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70a91e1a-474d-425f-845b-7045f63b7b2e", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "'''\n", + "base_64_img_str = response_body.get(\"artifacts\")[0].get(\"base64\")\n", + "image = Image.open(io.BytesIO(base64.decodebytes(bytes(base_64_img_str, \"utf-8\"))))\n", + "display(image)\n", + "'''" + ] + }, + { + "cell_type": "markdown", + "id": "14ba68e4-d476-4685-b78c-42fb564c8e09", + "metadata": {}, + "source": [ + "### 埋め込み表現の生成" + ] + }, + { + "cell_type": "markdown", + "id": "cabca638-3ed7-4a10-8d6c-a518e909e80d", + "metadata": {}, + "source": [ + "Titan Embeddings により文字列の埋め込み表現を取得することができます。 \n", + "埋め込み表現とは、文字列の性質を表現したベクトルであり、検索やレコメンデーション等で利用可能です。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7922f289-d60b-484d-b448-9d926fd852ff", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "# 入力文字列の埋め込み表現を取得する関数\n", + "def get_embedding(text: str) -> np.ndarray:\n", + " body = json.dumps({\n", + " \"inputText\": text\n", + " })\n", + "\n", + " modelId = \"amazon.titan-embed-text-v1\"\n", + " accept = '*/*'\n", + " contentType = 'application/json'\n", + "\n", + " response = bedrock_runtime_client.invoke_model(body=body, modelId=modelId, accept=accept, contentType=contentType)\n", + " response_body = json.loads(response.get('body').read())\n", + " # print(response)\n", + " response_embeddings = np.array(response_body.get('embedding'))\n", + " \n", + " return response_embeddings" + ] + }, + { + "cell_type": "markdown", + "id": "18637f44-1b4e-446d-9857-cc46e8518384", + "metadata": {}, + "source": [ + "出力結果は1536次元のベクトルになります" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "94e0d65b-dea8-4b1c-a13d-9566b4ccb8bf", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "result = get_embedding('日本で一番高い山は?')\n", + "print(result[:20])\n", + "print('shape:', result.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "403a7497-a67f-409a-b122-39c7e1b9b5af", + "metadata": { + "tags": [] + }, + "source": [ + "ベクトルの類似度を計算することで、2つの文章が意味合いとして似ている度合いを定量化することができます。 \n", + "ここでは、文書どうしの類似度計算によく使われる指標である、[コサイン類似度](https://atmarkit.itmedia.co.jp/ait/articles/2112/08/news020.html)を使って、2つの文章を比較します。 " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47b2694b-17cf-4ff8-b4cb-ffbd9f0b422d", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# 2つのベクトルのコサイン類似度を計算する関数\n", + "def cos_sim(v1, v2):\n", + " return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "08d6687c-36d0-4297-b9fe-2936310609ad", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "print(cos_sim(get_embedding('日本で一番高い山は?'), get_embedding('日本最高峰とされるのは?')))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1565883f-0b38-40b7-bcbd-a5ba483346ae", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "print(cos_sim(get_embedding('日本で一番高い山は?'), get_embedding('バナナはおやつに入りますか?')))" + ] + }, + { + "cell_type": "markdown", + "id": "e5318488-8bbc-4be8-93bd-29706fd7d1f1", + "metadata": {}, + "source": [ + "類似する文章のコサイン類似度は高く、話題が異なる文章は低くなることがわかります。 " + ] + }, + { + "cell_type": "markdown", + "id": "56d68a4e-5ede-4b54-9c10-71436707c6c1", + "metadata": {}, + "source": [ + "## まとめ" + ] + }, + { + "cell_type": "markdown", + "id": "391bc6f0-dab2-4eb6-b66b-109c6d0df9c7", + "metadata": { + "tags": [] + }, + "source": [ + "このノートブックでは、AWS Python SDK(boto3) や LangChain を用いて Amazon Bedrock のモデルを呼び出すための基本的な方法をご紹介しました。 \n", + "次の章からは、より実践的に活用するための方法をご紹介していきます。" + ] + } + ], + "metadata": { + "availableInstances": [ + { + "_defaultOrder": 0, + "_isFastLaunch": true, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 4, + "name": "ml.t3.medium", + "vcpuNum": 2 + }, + { + "_defaultOrder": 1, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 8, + "name": "ml.t3.large", + "vcpuNum": 2 + }, + { + "_defaultOrder": 2, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 16, + "name": "ml.t3.xlarge", + "vcpuNum": 4 + }, + { + "_defaultOrder": 3, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 32, + "name": "ml.t3.2xlarge", + "vcpuNum": 8 + }, + { + "_defaultOrder": 4, + "_isFastLaunch": true, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 8, + "name": "ml.m5.large", + "vcpuNum": 2 + }, + { + "_defaultOrder": 5, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 16, + "name": "ml.m5.xlarge", + "vcpuNum": 4 + }, + { + "_defaultOrder": 6, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 32, + "name": "ml.m5.2xlarge", + "vcpuNum": 8 + }, + { + "_defaultOrder": 7, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 64, + "name": "ml.m5.4xlarge", + "vcpuNum": 16 + }, + { + "_defaultOrder": 8, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 128, + "name": "ml.m5.8xlarge", + "vcpuNum": 32 + }, + { + "_defaultOrder": 9, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 192, + "name": "ml.m5.12xlarge", + "vcpuNum": 48 + }, + { + "_defaultOrder": 10, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 256, + "name": "ml.m5.16xlarge", + "vcpuNum": 64 + }, + { + "_defaultOrder": 11, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 384, + "name": "ml.m5.24xlarge", + "vcpuNum": 96 + }, + { + "_defaultOrder": 12, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 8, + "name": "ml.m5d.large", + "vcpuNum": 2 + }, + { + "_defaultOrder": 13, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 16, + "name": "ml.m5d.xlarge", + "vcpuNum": 4 + }, + { + "_defaultOrder": 14, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 32, + "name": "ml.m5d.2xlarge", + "vcpuNum": 8 + }, + { + "_defaultOrder": 15, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 64, + "name": "ml.m5d.4xlarge", + "vcpuNum": 16 + }, + { + "_defaultOrder": 16, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 128, + "name": "ml.m5d.8xlarge", + "vcpuNum": 32 + }, + { + "_defaultOrder": 17, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 192, + "name": "ml.m5d.12xlarge", + "vcpuNum": 48 + }, + { + "_defaultOrder": 18, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 256, + "name": "ml.m5d.16xlarge", + "vcpuNum": 64 + }, + { + "_defaultOrder": 19, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 384, + "name": "ml.m5d.24xlarge", + "vcpuNum": 96 + }, + { + "_defaultOrder": 20, + "_isFastLaunch": false, + "category": "General purpose", + "gpuNum": 0, + "hideHardwareSpecs": true, + "memoryGiB": 0, + "name": "ml.geospatial.interactive", + "supportedImageNames": [ + "sagemaker-geospatial-v1-0" + ], + "vcpuNum": 0 + }, + { + "_defaultOrder": 21, + "_isFastLaunch": true, + "category": "Compute optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 4, + "name": "ml.c5.large", + "vcpuNum": 2 + }, + { + "_defaultOrder": 22, + "_isFastLaunch": false, + "category": "Compute optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 8, + "name": "ml.c5.xlarge", + "vcpuNum": 4 + }, + { + "_defaultOrder": 23, + "_isFastLaunch": false, + "category": "Compute optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 16, + "name": "ml.c5.2xlarge", + "vcpuNum": 8 + }, + { + "_defaultOrder": 24, + "_isFastLaunch": false, + "category": "Compute optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 32, + "name": "ml.c5.4xlarge", + "vcpuNum": 16 + }, + { + "_defaultOrder": 25, + "_isFastLaunch": false, + "category": "Compute optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 72, + "name": "ml.c5.9xlarge", + "vcpuNum": 36 + }, + { + "_defaultOrder": 26, + "_isFastLaunch": false, + "category": "Compute optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 96, + "name": "ml.c5.12xlarge", + "vcpuNum": 48 + }, + { + "_defaultOrder": 27, + "_isFastLaunch": false, + "category": "Compute optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 144, + "name": "ml.c5.18xlarge", + "vcpuNum": 72 + }, + { + "_defaultOrder": 28, + "_isFastLaunch": false, + "category": "Compute optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 192, + "name": "ml.c5.24xlarge", + "vcpuNum": 96 + }, + { + "_defaultOrder": 29, + "_isFastLaunch": true, + "category": "Accelerated computing", + "gpuNum": 1, + "hideHardwareSpecs": false, + "memoryGiB": 16, + "name": "ml.g4dn.xlarge", + "vcpuNum": 4 + }, + { + "_defaultOrder": 30, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 1, + "hideHardwareSpecs": false, + "memoryGiB": 32, + "name": "ml.g4dn.2xlarge", + "vcpuNum": 8 + }, + { + "_defaultOrder": 31, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 1, + "hideHardwareSpecs": false, + "memoryGiB": 64, + "name": "ml.g4dn.4xlarge", + "vcpuNum": 16 + }, + { + "_defaultOrder": 32, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 1, + "hideHardwareSpecs": false, + "memoryGiB": 128, + "name": "ml.g4dn.8xlarge", + "vcpuNum": 32 + }, + { + "_defaultOrder": 33, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 4, + "hideHardwareSpecs": false, + "memoryGiB": 192, + "name": "ml.g4dn.12xlarge", + "vcpuNum": 48 + }, + { + "_defaultOrder": 34, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 1, + "hideHardwareSpecs": false, + "memoryGiB": 256, + "name": "ml.g4dn.16xlarge", + "vcpuNum": 64 + }, + { + "_defaultOrder": 35, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 1, + "hideHardwareSpecs": false, + "memoryGiB": 61, + "name": "ml.p3.2xlarge", + "vcpuNum": 8 + }, + { + "_defaultOrder": 36, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 4, + "hideHardwareSpecs": false, + "memoryGiB": 244, + "name": "ml.p3.8xlarge", + "vcpuNum": 32 + }, + { + "_defaultOrder": 37, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 8, + "hideHardwareSpecs": false, + "memoryGiB": 488, + "name": "ml.p3.16xlarge", + "vcpuNum": 64 + }, + { + "_defaultOrder": 38, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 8, + "hideHardwareSpecs": false, + "memoryGiB": 768, + "name": "ml.p3dn.24xlarge", + "vcpuNum": 96 + }, + { + "_defaultOrder": 39, + "_isFastLaunch": false, + "category": "Memory Optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 16, + "name": "ml.r5.large", + "vcpuNum": 2 + }, + { + "_defaultOrder": 40, + "_isFastLaunch": false, + "category": "Memory Optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 32, + "name": "ml.r5.xlarge", + "vcpuNum": 4 + }, + { + "_defaultOrder": 41, + "_isFastLaunch": false, + "category": "Memory Optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 64, + "name": "ml.r5.2xlarge", + "vcpuNum": 8 + }, + { + "_defaultOrder": 42, + "_isFastLaunch": false, + "category": "Memory Optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 128, + "name": "ml.r5.4xlarge", + "vcpuNum": 16 + }, + { + "_defaultOrder": 43, + "_isFastLaunch": false, + "category": "Memory Optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 256, + "name": "ml.r5.8xlarge", + "vcpuNum": 32 + }, + { + "_defaultOrder": 44, + "_isFastLaunch": false, + "category": "Memory Optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 384, + "name": "ml.r5.12xlarge", + "vcpuNum": 48 + }, + { + "_defaultOrder": 45, + "_isFastLaunch": false, + "category": "Memory Optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 512, + "name": "ml.r5.16xlarge", + "vcpuNum": 64 + }, + { + "_defaultOrder": 46, + "_isFastLaunch": false, + "category": "Memory Optimized", + "gpuNum": 0, + "hideHardwareSpecs": false, + "memoryGiB": 768, + "name": "ml.r5.24xlarge", + "vcpuNum": 96 + }, + { + "_defaultOrder": 47, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 1, + "hideHardwareSpecs": false, + "memoryGiB": 16, + "name": "ml.g5.xlarge", + "vcpuNum": 4 + }, + { + "_defaultOrder": 48, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 1, + "hideHardwareSpecs": false, + "memoryGiB": 32, + "name": "ml.g5.2xlarge", + "vcpuNum": 8 + }, + { + "_defaultOrder": 49, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 1, + "hideHardwareSpecs": false, + "memoryGiB": 64, + "name": "ml.g5.4xlarge", + "vcpuNum": 16 + }, + { + "_defaultOrder": 50, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 1, + "hideHardwareSpecs": false, + "memoryGiB": 128, + "name": "ml.g5.8xlarge", + "vcpuNum": 32 + }, + { + "_defaultOrder": 51, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 1, + "hideHardwareSpecs": false, + "memoryGiB": 256, + "name": "ml.g5.16xlarge", + "vcpuNum": 64 + }, + { + "_defaultOrder": 52, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 4, + "hideHardwareSpecs": false, + "memoryGiB": 192, + "name": "ml.g5.12xlarge", + "vcpuNum": 48 + }, + { + "_defaultOrder": 53, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 4, + "hideHardwareSpecs": false, + "memoryGiB": 384, + "name": "ml.g5.24xlarge", + "vcpuNum": 96 + }, + { + "_defaultOrder": 54, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 8, + "hideHardwareSpecs": false, + "memoryGiB": 768, + "name": "ml.g5.48xlarge", + "vcpuNum": 192 + }, + { + "_defaultOrder": 55, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 8, + "hideHardwareSpecs": false, + "memoryGiB": 1152, + "name": "ml.p4d.24xlarge", + "vcpuNum": 96 + }, + { + "_defaultOrder": 56, + "_isFastLaunch": false, + "category": "Accelerated computing", + "gpuNum": 8, + "hideHardwareSpecs": false, + "memoryGiB": 1152, + "name": "ml.p4de.24xlarge", + "vcpuNum": 96 + } + ], + "instance_type": "ml.t3.medium", + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/bedrock/bedrock-beginners-handson/sample.png b/bedrock/bedrock-beginners-handson/sample.png new file mode 100644 index 0000000..0e4369d Binary files /dev/null and b/bedrock/bedrock-beginners-handson/sample.png differ