diff --git a/.doc_gen/metadata/bedrock-runtime_metadata.yaml b/.doc_gen/metadata/bedrock-runtime_metadata.yaml index 952c026e3e5..a2f5249abf9 100644 --- a/.doc_gen/metadata/bedrock-runtime_metadata.yaml +++ b/.doc_gen/metadata/bedrock-runtime_metadata.yaml @@ -24,6 +24,73 @@ bedrock-runtime_Hello: services: bedrock-runtime: {InvokeModel} +# Amazon Titan - Embeddings +bedrock-runtime_TitanTextEmbeddingsG1_InvokeModel: + title: Invoke Amazon Titan Text Embeddings G1 on &BR; + title_abbrev: "Amazon Titan Text Embeddings G1" + synopsis_list: + - Get started creating your first embedding. + - Create embeddings and process all response fields. + category: Invoke model examples + languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/bedrock-runtime + excerpts: + - description: Create your first embedding with Amazon Titan Text Embeddings G1. + snippet_tags: + - bedrock-runtime.java2.InvokeModel_TitanTextEmbeddingsG1_Quickstart + - description: Invoke Amazon Titan Text Embeddings G1 and process all response fields. + snippet_tags: + - bedrock-runtime.java2.InvokeModel_TitanTextEmbeddingsG1_AdditionalFields + Python: + versions: + - sdk_version: 3 + github: python/example_code/bedrock-runtime + excerpts: + - description: Create your first embedding with Amazon Titan Text Embeddings G1. + snippet_tags: + - python.example_code.bedrock-runtime.InvokeModel_TitanTextEmbeddingsG1_Quickstart + - description: Invoke Amazon Titan Text Embeddings G1 and process all response fields. + snippet_tags: + - python.example_code.bedrock-runtime.InvokeModel_TitanTextEmbeddingsG1_AdditionalFields + services: + bedrock-runtime: {InvokeModel} + +bedrock-runtime_TitanTextEmbeddingsV2_InvokeModel: + title: Invoke Amazon Titan Text Embeddings V2 on &BR; + title_abbrev: "Amazon Titan Text Embeddings V2" + synopsis_list: + - Get started creating your first embedding. + - Create embeddings configuring the number of dimensions and normalization. + category: Invoke model examples + languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/bedrock-runtime + excerpts: + - description: Create your first embedding with Titan Text Embeddings V2. + snippet_tags: + - bedrock-runtime.java2.InvokeModel_TitanTextEmbeddingsV2_Quickstart + - description: Invoke Titan Text Embeddings V2 configuring the number of dimensions and normalization. + snippet_tags: + - bedrock-runtime.java2.InvokeModel_TitanTextEmbeddingsV2_AdditionalFields + Python: + versions: + - sdk_version: 3 + github: python/example_code/bedrock-runtime + excerpts: + - description: Create your first embedding with Titan Text Embeddings V2. + snippet_tags: + - python.example_code.bedrock-runtime.InvokeModel_TitanTextEmbeddingsG1_Quickstart + - description: Invoke Titan Text Embeddings V2 configuring the number of dimensions and normalization. + snippet_tags: + - python.example_code.bedrock-runtime.InvokeModel_TitanTextEmbeddingsG1_AdditionalFields + services: + bedrock-runtime: {InvokeModel} + bedrock-runtime_InvokeAmazonTitanImageGeneratorForImageGeneration: title: Invoke Amazon Titan Image G1 on &BR; to generate an image title_abbrev: 'Amazon Titan: Image generation' diff --git a/javav2/example_code/bedrock-runtime/README.md b/javav2/example_code/bedrock-runtime/README.md index 2aceb3cda3f..fdea32ad458 100644 --- a/javav2/example_code/bedrock-runtime/README.md +++ b/javav2/example_code/bedrock-runtime/README.md @@ -40,8 +40,10 @@ functions within the same service. ### Invoke model examples -- [AI21 Labs Jurassic-2: Text generation](src/main/java/com/example/bedrockruntime/InvokeModelAsync.java#L205) -- [Amazon Titan: Image generation](src/main/java/com/example/bedrockruntime/InvokeModelAsync.java#L338) +- [AI21 Labs Jurassic-2: Text generation](src/main/java/com/example/bedrockruntime/InvokeModelAsync.java#L208) +- [Amazon Titan Text Embeddings G1](src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/G1InvokeModelQuickstart.java#L11) +- [Amazon Titan Text Embeddings V2](src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/V2InvokeModelQuickstart.java#L11) +- [Amazon Titan: Image generation](src/main/java/com/example/bedrockruntime/InvokeModelAsync.java#L343) - [Anthropic Claude 2: Real-time response stream processing](src/main/java/com/example/bedrockruntime/Claude2.java#L65) - [Anthropic Claude 2: Text generation](src/main/java/com/example/bedrockruntime/InvokeModel.java#L112) - [Anthropic Claude 3: Real-time response stream processing](src/main/java/com/example/bedrockruntime/Claude3.java#L49) @@ -50,8 +52,8 @@ functions within the same service. - [Meta Llama 3: Text generation](src/main/java/com/example/bedrockruntime/models/meta/llama3/InvokeModelQuickstart.java#L13) - [Meta Llama 3: Text generation with response stream](src/main/java/com/example/bedrockruntime/models/meta/llama3/InvokeModelWithResponseStreamQuickstart.java#L14) - [Mistral AI: Text generation with Mistral 7B Instruct](src/main/java/com/example/bedrockruntime/InvokeModelAsync.java#L33) -- [Mistral AI: Text generation with Mixtral 8x7B Instruct](src/main/java/com/example/bedrockruntime/InvokeModelAsync.java#L88) -- [Stable Diffusion: Image generation](src/main/java/com/example/bedrockruntime/InvokeModelAsync.java#L268) +- [Mistral AI: Text generation with Mixtral 8x7B Instruct](src/main/java/com/example/bedrockruntime/InvokeModelAsync.java#L89) +- [Stable Diffusion: Image generation](src/main/java/com/example/bedrockruntime/InvokeModelAsync.java#L272) diff --git a/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/InvokeModelAsync.java b/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/InvokeModelAsync.java index ef4361ee850..0b22bb2995f 100644 --- a/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/InvokeModelAsync.java +++ b/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/InvokeModelAsync.java @@ -23,14 +23,15 @@ /** * Before running this Java V2 code example, set up your development * environment, including your credentials. - * + *

* For more information, see the following documentation topic: - * + *

* https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class InvokeModelAsync { // snippet-start:[bedrock-runtime.java2.invoke_mistral_7b_async.main] + /** * Asynchronously invokes the Mistral 7B model to run an inference based on the provided input. * @@ -56,15 +57,15 @@ public static List invokeMistral7B(String prompt) { .toString(); CompletableFuture completableFuture = client.invokeModel(request -> request - .accept("application/json") - .contentType("application/json") - .body(SdkBytes.fromUtf8String(payload)) - .modelId(modelId)) - .whenComplete((response, exception) -> { - if (exception != null) { - System.out.println("Model invocation failed: " + exception); - } - }); + .accept("application/json") + .contentType("application/json") + .body(SdkBytes.fromUtf8String(payload)) + .modelId(modelId)) + .whenComplete((response, exception) -> { + if (exception != null) { + System.out.println("Model invocation failed: " + exception); + } + }); try { InvokeModelResponse response = completableFuture.get(); @@ -86,6 +87,7 @@ public static List invokeMistral7B(String prompt) { // snippet-end:[bedrock-runtime.java2.invoke_mistral_7b_async.main] // snippet-start:[bedrock-runtime.java2.invoke_mixtral_8x7b_async.main] + /** * Asynchronously invokes the Mixtral 8x7B model to run an inference based on the provided input. * @@ -141,6 +143,7 @@ public static List invokeMixtral8x7B(String prompt) { // snippet-end:[bedrock-runtime.java2.invoke_mixtral_8x7b_async.main] // snippet-start:[bedrock-runtime.java2.invoke_claude_async.main] + /** * Asynchronously invokes the Anthropic Claude 2 model to run an inference based * on the provided input. @@ -203,6 +206,7 @@ public static String invokeClaude(String prompt) { // snippet-end:[bedrock-runtime.java2.invoke_claude_async.main] // snippet-start:[bedrock-runtime.java2.invoke_jurassic-2_async.main] + /** * Asynchronously invokes the AI21 Labs Jurassic-2 model to run an inference * based on the provided input. @@ -266,6 +270,7 @@ public static String invokeJurassic2(String prompt) { // snippet-end:[bedrock-runtime.java2.invoke_jurassic-2_async.main] // snippet-start:[bedrock-runtime.java2.invoke_stable_diffusion_async.main] + /** * Asynchronously invokes the Stability.ai Stable Diffusion XL model to create * an image based on the provided input. @@ -285,7 +290,7 @@ public static String invokeStableDiffusion(String prompt, long seed, String styl * https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-stability-diffusion.html */ - String stableDiffusionModelId = "stability.stable-diffusion-xl"; + String stableDiffusionModelId = "stability.stable-diffusion-xl-v1"; BedrockRuntimeAsyncClient client = BedrockRuntimeAsyncClient.builder() .region(Region.US_EAST_1) @@ -336,6 +341,7 @@ public static String invokeStableDiffusion(String prompt, long seed, String styl // snippet-end:[bedrock-runtime.java2.invoke_stable_diffusion_async.main] // snippet-start:[bedrock-runtime.java2.invoke_titan_image_async.main] + /** * Invokes the Amazon Titan image generation model to create an image using the * input diff --git a/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/libs/ScenarioRunner.java b/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/libs/ScenarioRunner.java new file mode 100644 index 00000000000..c68bd779594 --- /dev/null +++ b/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/libs/ScenarioRunner.java @@ -0,0 +1,71 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.bedrockruntime.libs; + +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +public class ScenarioRunner { + private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + private final List scenarios = new ArrayList<>(); + + public void printHeader() { + System.out.println("*".repeat(80)); + System.out.println("*" + " ".repeat(78) + "*"); + System.out.println("* Welcome to the Amazon Bedrock demo!" + " ".repeat(41) + "*"); + System.out.println("* " + "-".repeat(74) + " *"); + System.out.println("*" + " ".repeat(78) + "*"); + System.out.println("* This demo showcases the following scenarios:" + " ".repeat(32) + "*"); + + int scenarioNumber = 1; + scenarios.forEach(scenario -> { + System.out.println("*" + " ".repeat(78) + "*"); + System.out.println("* " + scenarioNumber + ". " + scenario + "." + " ".repeat(20) + "*"); + }); + + System.out.println("*" + " ".repeat(78) + "*"); + System.out.println("*".repeat(80)); + } + + public void printScenarioHeader(String title) { + System.out.println("=".repeat(80)); + System.out.println(title); + System.out.println("=".repeat(80)); + } + + public void printCurrentResponse(JSONObject response) throws IOException { + printCurrentResponse(response.toString(2)); + } + + public void printCurrentResponse(String text) throws IOException { + System.out.println("-".repeat(80)); + promptUser("Press Enter to see the detailed response..."); + System.out.println(text); + System.out.println("-".repeat(80)); + } + + public void printFooter() { + System.out.println("\n" + "*".repeat(80)); + System.out.println("Thanks for running the Amazon Bedrock demo!"); + System.out.println("=".repeat(80)); + System.out.println("For more examples across different programming languages check out:"); + System.out.println("https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html"); + System.out.println("*".repeat(80)); + } + + public void promptUser(String text) throws IOException { + System.out.printf("\n%s%n", text); + this.reader.readLine(); + } + + public ScenarioRunner addScenario(String title) { + this.scenarios.add(title); + return this; + } +} diff --git a/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/G1InvokeModelQuickstart.java b/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/G1InvokeModelQuickstart.java new file mode 100644 index 00000000000..0eff6cec3f4 --- /dev/null +++ b/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/G1InvokeModelQuickstart.java @@ -0,0 +1,44 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.bedrockruntime.models.amazon.embeddings.text; + +import org.json.JSONObject; +import software.amazon.awssdk.core.SdkBytes; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient; + +// snippet-start:[bedrock-runtime.java2.InvokeModel_TitanTextEmbeddingsG1_Quickstart] +// Generate and print an embedding with Amazon Titan Text Embeddings G1. +public class G1InvokeModelQuickstart { + + public static void main(String[] args) { + + // Create a Bedrock Runtime client in the AWS Region of your choice. + var client = BedrockRuntimeClient.builder() + .region(Region.US_WEST_2) + .build(); + + // Set the model ID, e.g., Titan Text Embeddings G1. + var modelId = "amazon.titan-embed-text-v1"; + + // The text to convert into an embedding. + var inputText = "Please recommend books with a theme similar to the movie 'Inception'."; + + // Create a JSON payload using the model's native structure. + var request = new JSONObject().put("inputText", inputText); + + // Encode and send the request. + var response = client.invokeModel(req -> req + .body(SdkBytes.fromUtf8String(request.toString())) + .modelId(modelId)); + + // Decode the model's native response body. + var nativeResponse = new JSONObject(response.body().asUtf8String()); + + // Extract and print the generated embedding. + var embedding = nativeResponse.getJSONArray("embedding"); + System.out.println(embedding); + } +} +// snippet-end:[bedrock-runtime.java2.InvokeModel_TitanTextEmbeddingsG1_Quickstart] diff --git a/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/G1InvokeModelScenarios.java b/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/G1InvokeModelScenarios.java new file mode 100644 index 00000000000..f33e6f5abd6 --- /dev/null +++ b/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/G1InvokeModelScenarios.java @@ -0,0 +1,88 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.bedrockruntime.models.amazon.embeddings.text; + +import com.example.bedrockruntime.libs.ScenarioRunner; +import org.json.JSONObject; +import software.amazon.awssdk.core.SdkBytes; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient; + +import java.io.IOException; + +/** + * This program demonstrates how to use InvokeModel with Amazon Titan Text Embeddings G1 on Amazon Bedrock. + *

+ * For more examples in different programming languages check out the Amazon Bedrock User Guide at: + * https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html + */ + +public class G1InvokeModelScenarios { + // snippet-start:[bedrock-runtime.java2.InvokeModel_TitanTextEmbeddingsG1_AdditionalFields] + + /** + * Invoke Amazon Titan Text Embeddings G1 and print the response. + * + * @param inputText - The text to convert to an embedding. + * @return The {@link JSONObject} representing the model's response. + */ + public static JSONObject invokeModel(String inputText) { + + // Create a Bedrock Runtime client in the AWS Region of your choice. + var client = BedrockRuntimeClient.builder() + .region(Region.US_WEST_2) + .build(); + + // Set the model ID, e.g., Titan Text Embeddings G1. + var modelId = "amazon.titan-embed-text-v1"; + + // Format the request payload using Anthropic's native structure. + var nativeRequest = "{\"inputText\": \"" + inputText + "\"}"; + + // Encode and send the request. + var response = client.invokeModel(request -> { + request.body(SdkBytes.fromUtf8String(nativeRequest)); + request.modelId(modelId); + }); + + // Decode the model's response. + var modelResponse = new JSONObject(response.body().asUtf8String()); + + // Extract and print the generated embedding and the input text token count. + var embedding = modelResponse.getJSONArray("embedding"); + var inputTokenCount = modelResponse.getBigInteger("inputTextTokenCount"); + System.out.println("Embedding: " + embedding); + System.out.println("\nInput token count: " + inputTokenCount); + + // Return the model's native response. + return modelResponse; + } + // snippet-end:[bedrock-runtime.java2.InvokeModel_TitanTextEmbeddingsG1_AdditionalFields] + + public static void main(String[] args) throws IOException { + new Demo().run(); + } + + private static class Demo { + private final ScenarioRunner demo = new ScenarioRunner() + .addScenario("Create an embedding with custom inference parameters"); + + void run() throws IOException { + demo.printHeader(); + + var inputText = "Please recommend books with a theme similar to the movie 'Inception'."; + var response = runTextScenario(inputText); + demo.printCurrentResponse(response); + + demo.printFooter(); + } + + private JSONObject runTextScenario(String inputText) { + demo.printScenarioHeader("Scenario - Create an embedding with custom inference parameters:"); + System.out.printf("%nInput text: '%s'%n", inputText); + System.out.printf("Waiting for the response...%n"); + return invokeModel(inputText); + } + } +} diff --git a/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/V2InvokeModelQuickstart.java b/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/V2InvokeModelQuickstart.java new file mode 100644 index 00000000000..82344359541 --- /dev/null +++ b/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/V2InvokeModelQuickstart.java @@ -0,0 +1,44 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.bedrockruntime.models.amazon.embeddings.text; + +import org.json.JSONObject; +import software.amazon.awssdk.core.SdkBytes; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient; + +// snippet-start:[bedrock-runtime.java2.InvokeModel_TitanTextEmbeddingsV2_Quickstart] +// Generate and print an embedding with Amazon Titan Text Embeddings V2. +public class V2InvokeModelQuickstart { + + public static void main(String[] args) { + + // Create a Bedrock Runtime client in the AWS Region of your choice. + var client = BedrockRuntimeClient.builder() + .region(Region.US_WEST_2) + .build(); + + // Set the model ID, e.g., Titan Text Embeddings V2. + var modelId = "amazon.titan-embed-text-v2:0"; + + // The text to convert into an embedding. + var inputText = "Please recommend books with a theme similar to the movie 'Inception'."; + + // Create a JSON payload using the model's native structure. + var request = new JSONObject().put("inputText", inputText); + + // Encode and send the request. + var response = client.invokeModel(req -> req + .body(SdkBytes.fromUtf8String(request.toString())) + .modelId(modelId)); + + // Decode the model's native response body. + var nativeResponse = new JSONObject(response.body().asUtf8String()); + + // Extract and print the generated embedding. + var embedding = nativeResponse.getJSONArray("embedding"); + System.out.println(embedding); + } +} +// snippet-end:[bedrock-runtime.java2.InvokeModel_TitanTextEmbeddingsV2_Quickstart] diff --git a/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/V2InvokeModelScenarios.java b/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/V2InvokeModelScenarios.java new file mode 100644 index 00000000000..d1eed194cf1 --- /dev/null +++ b/javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/models/amazon/embeddings/text/V2InvokeModelScenarios.java @@ -0,0 +1,103 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.bedrockruntime.models.amazon.embeddings.text; + +import com.example.bedrockruntime.libs.ScenarioRunner; +import org.json.JSONObject; +import software.amazon.awssdk.core.SdkBytes; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient; + +import java.io.IOException; + +/** + * This program demonstrates how to use InvokeModel with Amazon Titan Text Embeddings V2 on Amazon Bedrock. + *

+ * For more examples in different programming languages check out the Amazon Bedrock User Guide at: + * https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html + */ + +public class V2InvokeModelScenarios { + // snippet-start:[bedrock-runtime.java2.InvokeModel_TitanTextEmbeddingsV2_AdditionalFields] + + /** + * Invoke Amazon Titan Text Embeddings v2 with additional inference parameters. + * + * @param inputText - The text to convert to an embedding. + * @param dimensions - The number of dimensions the output embeddings should have. + * Values accepted by the model: 256, 512, 1024. + * @param normalize - A flag indicating whether or not to normalize the output embeddings. + * @return The {@link JSONObject} representing the model's response. + */ + public static JSONObject invokeModel(String inputText, int dimensions, boolean normalize) { + + // Create a Bedrock Runtime client in the AWS Region of your choice. + var client = BedrockRuntimeClient.builder() + .region(Region.US_WEST_2) + .build(); + + // Set the model ID, e.g., Titan Embed Text v2.0. + var modelId = "amazon.titan-embed-text-v2:0"; + + // Create the request for the model. + var nativeRequest = """ + { + "inputText": "%s", + "dimensions": %d, + "normalize": %b + } + """.formatted(inputText, dimensions, normalize); + + // Encode and send the request. + var response = client.invokeModel(request -> { + request.body(SdkBytes.fromUtf8String(nativeRequest)); + request.modelId(modelId); + }); + + // Decode the model's response. + var modelResponse = new JSONObject(response.body().asUtf8String()); + + // Extract and print the generated embedding and the input text token count. + var embedding = modelResponse.getJSONArray("embedding"); + var inputTokenCount = modelResponse.getBigInteger("inputTextTokenCount"); + System.out.println("Embedding: " + embedding); + System.out.println("\nInput token count: " + inputTokenCount); + + // Return the model's native response. + return modelResponse; + } + // snippet-end:[bedrock-runtime.java2.InvokeModel_TitanTextEmbeddingsV2_AdditionalFields] + + public static void main(String[] args) throws IOException { + new Demo().run(); + } + + private static class Demo { + private final ScenarioRunner demo = new ScenarioRunner() + .addScenario("Create an embedding with custom inference parameters"); + + void run() throws IOException { + demo.printHeader(); + + var inputText = "Please recommend books with a theme similar to the movie 'Inception'."; + var dimensions = 256; + var normalize = true; + var response = runTextScenario(inputText, dimensions, normalize); + demo.printCurrentResponse(response); + + demo.printFooter(); + } + + private JSONObject runTextScenario(String inputText, int dimensions, boolean normalize) { + demo.printScenarioHeader("Scenario - Create an embedding with custom inference parameters:"); + + System.out.printf("%nInput text: '%s'%n", inputText); + System.out.printf("Dimensions: '%d'%n", dimensions); + System.out.printf("Normalize: '%b'%n%n", normalize); + + System.out.printf("Waiting for the response...%n"); + return invokeModel(inputText, dimensions, normalize); + } + } +} diff --git a/javav2/example_code/bedrock-runtime/src/test/java/amazontitan/TestTitanEmbeddingsG1.java b/javav2/example_code/bedrock-runtime/src/test/java/amazontitan/TestTitanEmbeddingsG1.java new file mode 100644 index 00000000000..2daaaa212af --- /dev/null +++ b/javav2/example_code/bedrock-runtime/src/test/java/amazontitan/TestTitanEmbeddingsG1.java @@ -0,0 +1,29 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package amazontitan; + +import com.example.bedrockruntime.models.amazon.embeddings.text.G1InvokeModelQuickstart; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import static com.example.bedrockruntime.models.amazon.embeddings.text.G1InvokeModelScenarios.invokeModel; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertFalse; + +@Tag("IntegrationTest") +@TestInstance(TestInstance.Lifecycle.PER_METHOD) +public class TestTitanEmbeddingsG1 { + @Test + void Quickstart() { + assertDoesNotThrow(() -> G1InvokeModelQuickstart.main(null)); + } + + @Test + void InvokeModel() { + var inputText = "A text input"; + var response = invokeModel(inputText); + assertFalse(response.getJSONArray("embedding").isEmpty()); + } +} diff --git a/javav2/example_code/bedrock-runtime/src/test/java/amazontitan/TestTitanEmbeddingsV2.java b/javav2/example_code/bedrock-runtime/src/test/java/amazontitan/TestTitanEmbeddingsV2.java new file mode 100644 index 00000000000..6313aac2567 --- /dev/null +++ b/javav2/example_code/bedrock-runtime/src/test/java/amazontitan/TestTitanEmbeddingsV2.java @@ -0,0 +1,31 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package amazontitan; + +import com.example.bedrockruntime.models.amazon.embeddings.text.V2InvokeModelQuickstart; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import static com.example.bedrockruntime.models.amazon.embeddings.text.V2InvokeModelScenarios.invokeModel; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertFalse; + +@Tag("IntegrationTest") +@TestInstance(TestInstance.Lifecycle.PER_METHOD) +public class TestTitanEmbeddingsV2 { + @Test + void Quickstart() { + assertDoesNotThrow(() -> V2InvokeModelQuickstart.main(null)); + } + + @Test + void InvokeModel() { + var inputText = "A text input"; + var dimensions = 256; + var normalize = true; + var response = invokeModel(inputText, dimensions, normalize); + assertFalse(response.getJSONArray("embedding").isEmpty()); + } +} diff --git a/python/example_code/bedrock-agent/requirements.txt b/python/example_code/bedrock-agent/requirements.txt index 6c7a79a78b3..4b8fab22567 100644 --- a/python/example_code/bedrock-agent/requirements.txt +++ b/python/example_code/bedrock-agent/requirements.txt @@ -1,6 +1,9 @@ -boto3==1.33.8 -botocore==1.33.8 +boto3==1.34.98 +botocore==1.34.98 +certifi==2023.11.17 +charset-normalizer==3.3.2 colorama==0.4.6 +idna==3.6 iniconfig==2.0.0 jmespath==1.0.1 packaging==23.2 @@ -8,6 +11,7 @@ pluggy==1.3.0 pytest==7.4.3 python-dateutil==2.8.2 PyYAML==6.0.1 -s3transfer==0.8.2 +requests==2.31.0 +s3transfer==0.10.1 six==1.16.0 urllib3==2.0.7 diff --git a/python/example_code/bedrock-runtime/README.md b/python/example_code/bedrock-runtime/README.md index 2d3fd43ff1b..4972e809683 100644 --- a/python/example_code/bedrock-runtime/README.md +++ b/python/example_code/bedrock-runtime/README.md @@ -39,6 +39,8 @@ python -m pip install -r requirements.txt ### Invoke model examples - [AI21 Labs Jurassic-2: Text generation](bedrock_runtime_wrapper.py#L79) +- [Amazon Titan Text Embeddings G1](models/amazon/titan_embeddings_text/g1_invoke_model_quickstart.py#L4) +- [Amazon Titan Text Embeddings V2](models/amazon/titan_embeddings_text/g1_invoke_model_quickstart.py#L4) - [Amazon Titan: Image generation](bedrock_runtime_wrapper.py#L238) - [Anthropic Claude 2: Real-time response stream processing](bedrock_runtime_wrapper.py#L283) - [Anthropic Claude 2: Text generation](bedrock_runtime_wrapper.py#L39) diff --git a/python/example_code/bedrock-runtime/models/amazon/titan_embeddings_text/g1_invoke_model_quickstart.py b/python/example_code/bedrock-runtime/models/amazon/titan_embeddings_text/g1_invoke_model_quickstart.py new file mode 100644 index 00000000000..4bcc9bec446 --- /dev/null +++ b/python/example_code/bedrock-runtime/models/amazon/titan_embeddings_text/g1_invoke_model_quickstart.py @@ -0,0 +1,32 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +# snippet-start:[python.example_code.bedrock-runtime.InvokeModel_TitanTextEmbeddingsG1_Quickstart] +# Generate and print an embedding with Amazon Titan Text Embeddings G1 + +import boto3 +import json + +# Create a Bedrock Runtime client in the AWS Region of your choice. +client = boto3.client("bedrock-runtime", region_name="us-west-2") + +# Set the model ID, e.g., Titan Text Embeddings G1. +model_id = "amazon.titan-embed-text-v1" + +# The text to convert to an embedding. +input_text = "Please recommend books with a theme similar to the movie 'Inception'." + +# Create the request for the model. +request = {"inputText": input_text} + +# Encode and send the request. +response = client.invoke_model(body=json.dumps(request), modelId=model_id) + +# Decode the model's native response body. +model_response = json.loads(response["body"].read()) + +# Extract and print the generated embedding. +embedding = model_response["embedding"] +print(embedding) + +# snippet-end:[python.example_code.bedrock-runtime.InvokeModel_TitanTextEmbeddingsG1_Quickstart] diff --git a/python/example_code/bedrock-runtime/models/amazon/titan_embeddings_text/g1_invoke_model_scenarios.py b/python/example_code/bedrock-runtime/models/amazon/titan_embeddings_text/g1_invoke_model_scenarios.py new file mode 100644 index 00000000000..5bc7e9866bc --- /dev/null +++ b/python/example_code/bedrock-runtime/models/amazon/titan_embeddings_text/g1_invoke_model_scenarios.py @@ -0,0 +1,92 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +""" +Purpose + +This class demonstrates how to use InvokeModel with Amazon Titan Text Embeddings G1 +on Amazon Bedrock. + +For more examples in different programming languages check out the Amazon Bedrock User Guide at: +https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html +""" + +import boto3 +import json +import pprint +import sys + +# Add relative path to include demo_tools in this code example without needing to set up. +sys.path.append("../..") +import demo_tools.question as q + + +# snippet-start:[python.example_code.bedrock-runtime.InvokeModel_TitanTextEmbeddingsG1_AdditionalFields] +def invoke_model(input_text, client=None): + """ + Invoke Amazon Titan Text Embeddings G1 and print the response. + + :param input_text: The text to convert to an embedding. + :param client: An optional Bedrock Runtime client instance. + Defaults to None if not provided. + :return: The model's response object. + """ + + # Create a Bedrock Runtime client if not provided. + client = client or boto3.client("bedrock-runtime", region_name="us-west-2") + + # Set the model ID, e.g., Titan Text Embeddings G1. + model_id = "amazon.titan-embed-text-v1" + + # Create the request for the model. + request = {"inputText": input_text} + + # Encode and send the request. + response = client.invoke_model( + body=json.dumps(request), + modelId=model_id, + ) + + # Decode the response + model_response = json.loads(response["body"].read()) + + # Extract and print the generated embedding and the input text token count. + embedding = model_response["embedding"] + input_token_count = model_response["inputTextTokenCount"] + + print(f"Embedding: {embedding}\n") + print(f"Input token count: {input_token_count}") + + return model_response + + +# snippet-end:[python.example_code.bedrock-runtime.InvokeModel_TitanTextEmbeddingsG1_AdditionalFields] + + +def run_demo(): + print(f"{'=' * 80}\nWelcome to the Amazon Bedrock demo!") + + print(f"{'=' * 80}\nDemo: Create an embedding\n{'-' * 80}") + print("Type an input text you'd like to turn into an embedding:") + input_text = q.ask("", q.non_empty) + + print(f"{'-' * 80}") + print(f"Embedding the text: '{input_text}'") + + print(f"{'-' * 80}") + response = invoke_model(input_text) + + input(f"{'-' * 80}\nPress Enter to see the detailed response...") + print("Returned response:") + pprint.pprint(response) + + print(f"{'=' * 80}\nThanks for running the Amazon Bedrock demo!") + print("For more examples in many different programming languages check out:") + print( + "https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html" + ) + print("=" * 80) + + +if __name__ == "__main__": + run_demo() diff --git a/python/example_code/bedrock-runtime/models/amazon/titan_embeddings_text/v2_invoke_model_quickstart.py b/python/example_code/bedrock-runtime/models/amazon/titan_embeddings_text/v2_invoke_model_quickstart.py new file mode 100644 index 00000000000..a29bdc75af0 --- /dev/null +++ b/python/example_code/bedrock-runtime/models/amazon/titan_embeddings_text/v2_invoke_model_quickstart.py @@ -0,0 +1,32 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +# snippet-start:[python.example_code.bedrock-runtime.InvokeModel_TitanTextEmbeddingsV2_Quickstart] +# Generate and print an embedding with Amazon Titan Text Embeddings V2. + +import boto3 +import json + +# Create a Bedrock Runtime client in the AWS Region of your choice. +client = boto3.client("bedrock-runtime", region_name="us-west-2") + +# Set the model ID, e.g., Titan Text Embeddings V2. +model_id = "amazon.titan-embed-text-v2:0" + +# The text to convert to an embedding. +input_text = "Please recommend books with a theme similar to the movie 'Inception'." + +# Create the request for the model. +request = {"inputText": input_text} + +# Encode and send the request. +response = client.invoke_model(body=json.dumps(request), modelId=model_id) + +# Decode the model's native response body. +model_response = json.loads(response["body"].read()) + +# Extract and print the generated embedding. +embedding = model_response["embedding"] +print(embedding) + +# snippet-end:[python.example_code.bedrock-runtime.InvokeModel_TitanTextEmbeddingsV2_Quickstart] diff --git a/python/example_code/bedrock-runtime/models/amazon/titan_embeddings_text/v2_invoke_model_scenarios.py b/python/example_code/bedrock-runtime/models/amazon/titan_embeddings_text/v2_invoke_model_scenarios.py new file mode 100644 index 00000000000..e33916569b7 --- /dev/null +++ b/python/example_code/bedrock-runtime/models/amazon/titan_embeddings_text/v2_invoke_model_scenarios.py @@ -0,0 +1,107 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +""" +Purpose + +This class demonstrates how to use InvokeModel with Amazon Titan Text Embeddings v2 +on Amazon Bedrock. + +For more examples in different programming languages check out the Amazon Bedrock User Guide at: +https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html +""" + +import boto3 +import json +import pprint +import sys + +# Add relative path to include demo_tools in this code example without needing to set up. +sys.path.append("../..") +import demo_tools.question as q + + +# snippet-start:[python.example_code.bedrock-runtime.InvokeModel_TitanTextEmbeddingsV2_AdditionalFields] +def invoke_model(input_text, dimensions, normalize, client=None): + """ + Invoke Amazon Titan Text Embeddings v2 with additional inference parameters. + + :param input_text: The text to convert to an embedding. + :param dimensions: The number of dimensions the output embeddings should have. + Accepted values: 256, 512, 1024. Default: 1024. + :param normalize: A flag indicating whether or not to normalize the output embeddings. + Default: True. + :param client: An optional Bedrock Runtime client instance. + Defaults to None if not provided. + :return: The model's response object. + """ + + # Create a Bedrock Runtime client if not provided. + client = client or boto3.client("bedrock-runtime", region_name="us-west-2") + + # Set the model ID, e.g., Titan Embed Text v2.0. + model_id = "amazon.titan-embed-text-v2:0" + + # Create the request for the model. + request = { + "inputText": input_text, + "dimensions": dimensions, + "normalize": normalize, + } + + # Encode and send the request. + response = client.invoke_model( + body=json.dumps(request), + modelId=model_id, + ) + + # Decode the response + model_response = json.loads(response["body"].read()) + + # Extract and print the generated embedding and the input text token count. + embedding = model_response["embedding"] + input_token_count = model_response["inputTextTokenCount"] + + print(f"Embedding: {embedding}\n") + print(f"Input token count: {input_token_count}") + + return model_response + + +# snippet-end:[python.example_code.bedrock-runtime.InvokeModel_TitanTextEmbeddingsV2_AdditionalFields] + + +def run_demo(): + print(f"{'=' * 80}\nWelcome to the Amazon Bedrock demo!") + + print(f"{'=' * 80}\nDemo: Create an embedding\n{'-' * 80}") + print("Type an input text you'd like to turn into an embedding:") + input_text = q.ask("", q.non_empty) + + valid_dimensions = [256, 512, 1024] + dimensions = valid_dimensions[ + q.choose("Select the number of dimensions: ", valid_dimensions) + ] + normalize = q.ask("Normalize [y/N]: ", q.is_yesno) + + print(f"{'-' * 80}") + print(f"Embedding the text: '{input_text}'") + print(f"Number of dimensions: {dimensions} - Normalized: {normalize}") + + print(f"{'-' * 80}") + response = invoke_model(input_text, dimensions, normalize) + + input(f"{'-' * 80}\nPress Enter to see the detailed response...") + print("Returned response:") + pprint.pprint(response) + + print(f"{'=' * 80}\nThanks for running the Amazon Bedrock demo!") + print("For more examples in many different programming languages check out:") + print( + "https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html" + ) + print("=" * 80) + + +if __name__ == "__main__": + run_demo() diff --git a/python/example_code/bedrock-runtime/models/meta/llama3/invoke_model_quickstart.py b/python/example_code/bedrock-runtime/models/meta/llama3/invoke_model_quickstart.py index 9aeceb38549..39c44211628 100644 --- a/python/example_code/bedrock-runtime/models/meta/llama3/invoke_model_quickstart.py +++ b/python/example_code/bedrock-runtime/models/meta/llama3/invoke_model_quickstart.py @@ -7,6 +7,7 @@ import boto3 import json + # Create a Bedrock Runtime client in the AWS Region of your choice. client = boto3.client("bedrock-runtime", region_name="us-west-2") diff --git a/python/example_code/bedrock-runtime/requirements.txt b/python/example_code/bedrock-runtime/requirements.txt index 346abda2894..53e4580c098 100644 --- a/python/example_code/bedrock-runtime/requirements.txt +++ b/python/example_code/bedrock-runtime/requirements.txt @@ -1,13 +1,13 @@ -boto3==1.34.55 -botocore==1.34.55 +boto3==1.34.98 +botocore==1.34.98 colorama==0.4.6 iniconfig==2.0.0 jmespath==1.0.1 -packaging==23.2 -pluggy==1.3.0 -pytest==7.4.3 -pytest-asyncio==0.21.1 -python-dateutil==2.8.2 -s3transfer==0.10.0 +packaging==24.0 +pluggy==1.5.0 +pytest==8.1.1 +pytest-asyncio==0.23.6 +python-dateutil==2.9.0.post0 +s3transfer==0.10.1 six==1.16.0 -urllib3==2.0.7 +urllib3==2.2.1 diff --git a/python/example_code/bedrock-runtime/test/models/amazon_titan/test_invoke_model.py b/python/example_code/bedrock-runtime/test/models/amazon_titan/test_invoke_model.py new file mode 100644 index 00000000000..9497d9f068c --- /dev/null +++ b/python/example_code/bedrock-runtime/test/models/amazon_titan/test_invoke_model.py @@ -0,0 +1,63 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +""" +Unit tests for: +- models/amazon/titan_embeddings_text/g1_invoke_model_scenarios.py +- models/amazon/titan_embeddings_text/v2_invoke_model_scenarios.py +""" + +import boto3 +import io +import json +import pytest + +from models.amazon.titan_embeddings_text.g1_invoke_model_scenarios import ( + invoke_model as invoke_embeddings_g1, +) +from models.amazon.titan_embeddings_text.v2_invoke_model_scenarios import ( + invoke_model as invoke_embeddings_v2, +) + +EMBEDDINGS_G1_MODEL_ID = "amazon.titan-embed-text-v1" +EMBEDDINGS_V2_MODEL_ID = "amazon.titan-embed-text-v2:0" + +client = boto3.client(service_name="bedrock-runtime", region_name="us-west-2") + + +def test_invoke_embeddings_g1(make_stubber): + input_text = "An input text." + expected_params = { + "modelId": EMBEDDINGS_G1_MODEL_ID, + "body": json.dumps({"inputText": input_text}), + } + response = { + "contentType": "application/json", + "body": io.BytesIO( + json.dumps({"embedding": [], "inputTextTokenCount": 1}).encode("utf-8") + ), + } + make_stubber(client).stub_invoke_model(expected_params, response) + result = invoke_embeddings_g1(input_text, client) + assert result is not None + + +def test_invoke_embeddings_v2(make_stubber): + input_text = "An input text." + dimensions = 1024 + normalize = True + expected_params = { + "modelId": EMBEDDINGS_V2_MODEL_ID, + "body": json.dumps( + {"inputText": input_text, "dimensions": dimensions, "normalize": normalize} + ), + } + response = { + "contentType": "application/json", + "body": io.BytesIO( + json.dumps({"embedding": [], "inputTextTokenCount": 1}).encode("utf-8") + ), + } + make_stubber(client).stub_invoke_model(expected_params, response) + result = invoke_embeddings_v2(input_text, dimensions, normalize, client) + assert result is not None diff --git a/python/example_code/bedrock-runtime/test/models/amazon_titan/test_invoke_model_quickstarts.py b/python/example_code/bedrock-runtime/test/models/amazon_titan/test_invoke_model_quickstarts.py new file mode 100644 index 00000000000..4b8bf3ca4aa --- /dev/null +++ b/python/example_code/bedrock-runtime/test/models/amazon_titan/test_invoke_model_quickstarts.py @@ -0,0 +1,40 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +""" +Integration tests for: +- models/amazon/titan_embeddings_text/g2_invoke_model_quickstart.py +- models/amazon/titan_embeddings_text/v2_invoke_model_quickstart.py +""" + +import pytest +import subprocess +import sys + + +@pytest.mark.integ +def test_titan_embeddings_text_g1_quickstart(): + result = subprocess.run( + [ + sys.executable, + "models/amazon/titan_embeddings_text/g1_invoke_model_quickstart.py", + ], + capture_output=True, + text=True, + ) + assert result.stdout != "" + assert result.returncode == 0 + + +@pytest.mark.integ +def test_titan_embeddings_text_v2_quickstart(): + result = subprocess.run( + [ + sys.executable, + "models/amazon/titan_embeddings_text/v2_invoke_model_quickstart.py", + ], + capture_output=True, + text=True, + ) + assert result.stdout != "" + assert result.returncode == 0 diff --git a/python/test_tools/bedrock_runtime_stubber.py b/python/test_tools/bedrock_runtime_stubber.py index 6ac95919308..a87a0ba90c9 100644 --- a/python/test_tools/bedrock_runtime_stubber.py +++ b/python/test_tools/bedrock_runtime_stubber.py @@ -29,6 +29,11 @@ def __init__(self, client, use_stubs=True): """ super().__init__(client, use_stubs) + def stub_invoke_model(self, expected_params, response, error_code=None): + self._stub_bifurcator( + "invoke_model", expected_params, response, error_code=error_code + ) + def stub_invoke_mistral_7b(self, prompt, error_code=None): expected_params = { "modelId": "mistral.mistral-7b-instruct-v0:2",