Skip to content

Commit

Permalink
feat: support amazon nova (#623)
Browse files Browse the repository at this point in the history
* support amazon nova

* コメント対応

* CI対応

* CI対応

* コメント反映

* update readme

---------

Co-authored-by: statefb <[email protected]>
  • Loading branch information
fsatsuki and statefb authored Dec 4, 2024
1 parent 2063700 commit aabc8b6
Show file tree
Hide file tree
Showing 12 changed files with 166 additions and 42 deletions.
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Bedrock Claude Chat
# Bedrock Claude Chat (Nova)

![](https://github.com/aws-samples/bedrock-claude-chat/actions/workflows/cdk.yml/badge.svg)

> [!Warning] > **V2 released. To update, please carefully review the [migration guide](./docs/migration/V1_TO_V2.md).** Without any care, **BOTS FROM V1 WILL BECOME UNUSABLE.**
> [!Warning]
> **V2 released. To update, please carefully review the [migration guide](./docs/migration/V1_TO_V2.md).** Without any care, **BOTS FROM V1 WILL BECOME UNUSABLE.**
This repository is a sample chatbot using the Anthropic company's LLM [Claude](https://www.anthropic.com/), one of the foundational models provided by [Amazon Bedrock](https://aws.amazon.com/bedrock/) for generative AI.

Expand All @@ -12,8 +13,6 @@ This repository is a sample chatbot using the Anthropic company's LLM [Claude](h

### Basic Conversation

Not only text but also images are available with [Anthropic's Claude 3](https://www.anthropic.com/news/claude-3-family). Currently we support `Haiku`, `Sonnet` and `Opus`.

![](./docs/imgs/demo.gif)

### Bot Personalization
Expand Down Expand Up @@ -64,7 +63,7 @@ By using the [Agent functionality](./docs/AGENT.md), your chatbot can automatica

## 🚀 Super-easy Deployment

- In the us-east-1 region, open [Bedrock Model access](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess) > `Manage model access` > Check `Anthropic / Claude 3 Haiku`, `Anthropic / Claude 3 Sonnet`, `Anthropic / Claude 3.5 Sonnet`, `Anthropic / Claude 3.5 Sonnet v2`, `Anthropic / Claude 3.5 Haiku`, `Amazon / Titan Text Embeddings V2` and `Cohere / Embed Multilingual` then `Save changes`.
- In the us-east-1 region, open [Bedrock Model access](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess) > `Manage model access` > Check all of `Anthropic / Claude 3`, all of `Amazon / Nova`, `Amazon / Titan Text Embeddings V2` and `Cohere / Embed Multilingual` then `Save changes`.

<details>
<summary>Screenshot</summary>
Expand Down
103 changes: 84 additions & 19 deletions backend/app/bedrock.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import os
from typing import TypeGuard
from typing import TypeGuard, Dict, Any, Optional, Tuple

from app.agents.tools.agent_tool import AgentTool
from app.config import BEDROCK_PRICING
Expand Down Expand Up @@ -46,6 +46,48 @@ def _is_conversation_role(role: str) -> TypeGuard[ConversationRoleType]:
return role in ["user", "assistant"]


def _is_nova_model(model: type_model_name) -> bool:
"""Check if the model is an Amazon Nova model"""
return model in ["amazon-nova-pro", "amazon-nova-lite", "amazon-nova-micro"]


def _prepare_nova_model_params(
model: type_model_name, generation_params: Optional[GenerationParamsModel] = None
) -> Tuple[InferenceConfigurationTypeDef, Dict[str, Any]]:
"""
Prepare inference configuration and additional model request fields for Nova models
> Note that Amazon Nova expects inference parameters as a JSON object under a inferenceConfig attribute. Amazon Nova also has an additional parameter "topK" that can be passed as an additional inference parameters. This parameter follows the same structure and is passed through the additionalModelRequestFields, as shown below.
https://docs.aws.amazon.com/nova/latest/userguide/getting-started-converse.html
"""
# Base inference configuration
inference_config: InferenceConfigurationTypeDef = {
"maxTokens": (
generation_params.max_tokens
if generation_params
else DEFAULT_GENERATION_CONFIG["max_tokens"]
),
"temperature": (
generation_params.temperature
if generation_params
else DEFAULT_GENERATION_CONFIG["temperature"]
),
"topP": (
generation_params.top_p
if generation_params
else DEFAULT_GENERATION_CONFIG["top_p"]
),
}

# Additional model request fields specific to Nova models
additional_fields: Dict[str, Any] = {"inferenceConfig": {}}

# Add top_k if specified in generation params
if generation_params and generation_params.top_k is not None:
additional_fields["inferenceConfig"]["topK"] = generation_params.top_k

return inference_config, additional_fields


def compose_args_for_converse_api(
messages: list[SimpleMessageModel],
model: type_model_name,
Expand Down Expand Up @@ -88,39 +130,55 @@ def process_content(c: ContentModel, role: str) -> list[ContentBlockTypeDef]:
if _is_conversation_role(message.role)
]

inference_config: InferenceConfigurationTypeDef
if generation_params:
inference_config = {
"maxTokens": generation_params.max_tokens,
"temperature": generation_params.temperature,
"topP": generation_params.top_p,
"stopSequences": generation_params.stop_sequences,
}
additional_model_request_fields = {
"top_k": generation_params.top_k,
}

# Prepare model-specific parameters
if _is_nova_model(model):
# Special handling for Nova models
inference_config, additional_model_request_fields = _prepare_nova_model_params(
model, generation_params
)
else:
# Standard handling for non-Nova models
inference_config = {
"maxTokens": DEFAULT_GENERATION_CONFIG["max_tokens"],
"temperature": DEFAULT_GENERATION_CONFIG["temperature"],
"topP": DEFAULT_GENERATION_CONFIG["top_p"],
"stopSequences": DEFAULT_GENERATION_CONFIG["stop_sequences"],
"maxTokens": (
generation_params.max_tokens
if generation_params
else DEFAULT_GENERATION_CONFIG["max_tokens"]
),
"temperature": (
generation_params.temperature
if generation_params
else DEFAULT_GENERATION_CONFIG["temperature"]
),
"topP": (
generation_params.top_p
if generation_params
else DEFAULT_GENERATION_CONFIG["top_p"]
),
"stopSequences": (
generation_params.stop_sequences
if generation_params
else DEFAULT_GENERATION_CONFIG.get("stop_sequences", [])
),
}
additional_model_request_fields = {
"top_k": DEFAULT_GENERATION_CONFIG["top_k"],
"top_k": (
generation_params.top_k
if generation_params
else DEFAULT_GENERATION_CONFIG["top_k"]
)
}

# Construct the base arguments
args: ConverseStreamRequestRequestTypeDef = {
"inferenceConfig": inference_config,
"additionalModelRequestFields": additional_model_request_fields,
"modelId": get_model_id(model),
"messages": arg_messages,
"system": [
{"text": instruction}
for instruction in instructions
if len(instruction) > 0
],
"additionalModelRequestFields": additional_model_request_fields,
}

if guardrail and guardrail.guardrail_arn and guardrail.guardrail_version:
Expand Down Expand Up @@ -193,6 +251,10 @@ def get_model_id(
"mistral-7b-instruct": "mistral.mistral-7b-instruct-v0:2",
"mixtral-8x7b-instruct": "mistral.mixtral-8x7b-instruct-v0:1",
"mistral-large": "mistral.mistral-large-2402-v1:0",
# New Amazon Nova models
"amazon-nova-pro": "amazon.nova-pro-v1:0",
"amazon-nova-lite": "amazon.nova-lite-v1:0",
"amazon-nova-micro": "amazon.nova-micro-v1:0",
}

# Ref: https://docs.aws.amazon.com/bedrock/latest/userguide/cross-region-inference-support.html
Expand All @@ -203,6 +265,9 @@ def get_model_id(
"claude-v3.5-sonnet",
"claude-v3.5-sonnet-v2",
"claude-v3.5-haiku",
"amazon-nova-pro",
"amazon-nova-lite",
"amazon-nova-micro",
}

supported_region_prefixes = {
Expand Down
9 changes: 9 additions & 0 deletions backend/app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ class EmbeddingConfig(TypedDict):
"mistral-7b-instruct": {"input": 0.00015, "output": 0.0002},
"mixtral-8x7b-instruct": {"input": 0.00045, "output": 0.0007},
"mistral-large": {"input": 0.008, "output": 0.024},
"amazon-nova-pro": {"input": 0.0008, "output": 0.0032},
"amazon-nova-lite": {"input": 0.00006, "output": 0.00024},
"amazon-nova-micro": {"input": 0.000035, "output": 0.00014},
},
"us-west-2": {
"claude-instant-v1": {
Expand All @@ -73,6 +76,9 @@ class EmbeddingConfig(TypedDict):
"mistral-7b-instruct": {"input": 0.00015, "output": 0.0002},
"mixtral-8x7b-instruct": {"input": 0.00045, "output": 0.0007},
"mistral-large": {"input": 0.008, "output": 0.024},
"amazon-nova-pro": {"input": 0.0008, "output": 0.0032},
"amazon-nova-lite": {"input": 0.00006, "output": 0.00024},
"amazon-nova-micro": {"input": 0.000035, "output": 0.00014},
},
"ap-northeast-1": {
"claude-instant-v1": {
Expand Down Expand Up @@ -102,5 +108,8 @@ class EmbeddingConfig(TypedDict):
"mistral-7b-instruct": {"input": 0.00015, "output": 0.0002},
"mixtral-8x7b-instruct": {"input": 0.00045, "output": 0.0007},
"mistral-large": {"input": 0.008, "output": 0.024},
"amazon-nova-pro": {"input": 0.0008, "output": 0.0032},
"amazon-nova-lite": {"input": 0.00006, "output": 0.00024},
"amazon-nova-micro": {"input": 0.000035, "output": 0.00014},
},
}
4 changes: 4 additions & 0 deletions backend/app/routes/schemas/conversation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
"mistral-7b-instruct",
"mixtral-8x7b-instruct",
"mistral-large",
# New Amazon Nova models
"amazon-nova-pro",
"amazon-nova-lite",
"amazon-nova-micro",
]


Expand Down
8 changes: 4 additions & 4 deletions docs/README_ja.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Bedrock Claude Chat
# Bedrock Claude Chat (Nova)

> [!Warning] > **V2 がリリースされました。** 更新する際は、[移行ガイド](./migration/V1_TO_V2.md)を必ずご確認ください。 **注意を払わずに進めると、V1 の BOT は使用できなくなります。**
> [!Warning]
> **V2 がリリースされました。** 更新する際は、[移行ガイド](./migration/V1_TO_V2.md)を必ずご確認ください。 **注意を払わずに進めると、V1 の BOT は使用できなくなります。**
このリポジトリは、生成系 AI を提供する[Amazon Bedrock](https://aws.amazon.com/jp/bedrock/)の基盤モデルの一つである、Anthropic 社製 LLM [Claude](https://www.anthropic.com/)を利用したチャットボットのサンプルです。

### 基本的な会話

[Claude 3](https://www.anthropic.com/news/claude-3-family)によるテキストと画像の両方を利用したチャットが可能です。現在`Haiku`および`Sonnet`、または`Opus`をサポートしています。
![](./imgs/demo_ja.gif)

### ボットのカスタマイズ
Expand All @@ -33,7 +33,7 @@

## 🚀 まずはお試し

- us-east-1 リージョンにて、[Bedrock Model access](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess) > `Manage model access` > `Anthropic / Claude 3 Haiku`, `Anthropic / Claude 3 Sonnet`, `Anthropic / Claude 3.5 Sonnet` `Cohere / Embed Multilingual`をチェックし、`Save changes`をクリックします
- us-east-1 リージョンにて、[Bedrock Model access](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess) > `Manage model access` > すべての`Anthropic / Claude 3`、 すべての `Amazon / Nova``Cohere / Embed Multilingual`をチェックし、`Save changes`をクリックします

<details>
<summary>スクリーンショット</summary>
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/@types/conversation.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ export type Model =
| 'claude-v3.5-haiku'
| 'mistral-7b-instruct'
| 'mixtral-8x7b-instruct'
| 'mistral-large';
| 'mistral-large'
| 'amazon-nova-pro'
| 'amazon-nova-lite'
| 'amazon-nova-micro';

export type Content = TextContent | ImageContent | AttachmentContent;

Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/InputChatContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -459,10 +459,11 @@ const InputChatContent = forwardRef<HTMLElement, Props>((props, focusInputRef) =
)}>
<div className="flex w-full">
<Textarea
className="m-1 bg-transparent pr-12 scrollbar-thin scrollbar-thumb-light-gray"
placeholder={props.placeholder ?? t('app.inputMessage')}
className="m-1 bg-transparent pr-12 scrollbar-thin scrollbar-thumb-light-gray"
placeholder={t('app.inputMessage')}
disabled={props.disabled}
noBorder
rows={3}
value={content}
onChange={setContent}
ref={focusInputRef}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const EDGE_MISTRAL_GENERATION_PARAMS = {

export const DEFAULT_GENERATION_CONFIG: GenerationParams = {
maxTokens: 2000,
topK: 250,
topK: 128,
topP: 0.999,
temperature: 0.6,
stopSequences: ['Human: ', 'Assistant: '],
Expand Down
26 changes: 26 additions & 0 deletions frontend/src/hooks/useModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ const CLAUDE_SUPPORTED_MEDIA_TYPES = [
'image/webp',
];

const NOVA_SUPPORTED_MEDIA_TYPES = [
'image/jpeg',
'image/png',
'image/gif',
'image/webp',
]

const useModelState = create<{
modelId: Model;
setModelId: (m: Model) => void;
Expand Down Expand Up @@ -75,6 +82,25 @@ const useModel = () => {
description: t('model.opus3.description'),
supportMediaType: CLAUDE_SUPPORTED_MEDIA_TYPES,
},
// New Amazon Nova models
{
modelId: 'amazon-nova-pro',
label: t('model.novaPro.label'),
description: t('model.novaPro.description'),
supportMediaType: NOVA_SUPPORTED_MEDIA_TYPES,
},
{
modelId: 'amazon-nova-lite',
label: t('model.novaLite.label'),
description: t('model.novaLite.description'),
supportMediaType: NOVA_SUPPORTED_MEDIA_TYPES,
},
{
modelId: 'amazon-nova-micro',
label: t('model.novaMicro.label'),
description: t('model.novaMicro.description'),
supportMediaType: [],
}
]
: [
{
Expand Down
14 changes: 13 additions & 1 deletion frontend/src/i18n/en/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const translation = {
app: {
name: 'Bedrock Claude Chat',
nameWithoutClaude: 'Bedrock Chat',
inputMessage: 'Send a message',
inputMessage: 'Can I Help You?',
starredBots: 'Starred Bots',
recentlyUsedBots: 'Recently Used Bots',
conversationHistory: 'History',
Expand Down Expand Up @@ -53,6 +53,18 @@ const translation = {
mistralLarge: {
label: 'Mistral Large',
},
novaPro: {
label: "Amazon Nova Pro",
description: 'A highly capable multimodal model with the best combination of accuracy, speed, and cost for a wide range of tasks.',
},
novaLite: {
label: 'Amazon Nova Lite',
description: 'A very low-cost multimodal model that is lightning fast for processing image, video, and text inputs.',
},
novaMicro: {
label: 'Amazon Nova Micro',
description: 'A text-only model that delivers the lowest latency responses in the Amazon Nova family of models at a very low cost.',
}
},
agent: {
label: 'Agent',
Expand Down
14 changes: 13 additions & 1 deletion frontend/src/i18n/ja/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const translation = {
app: {
name: 'Bedrock Claude Chat',
nameWithoutClaude: 'Bedrock Chat',
inputMessage: '入力してください',
inputMessage: 'お手伝いできることはありますか?',
starredBots: 'スター付きのボット',
recentlyUsedBots: '最近使用したボット',
conversationHistory: '会話履歴',
Expand Down Expand Up @@ -55,6 +55,18 @@ const translation = {
mistralLarge: {
label: 'Mistral Large',
},
novaPro: {
label: "Amazon Nova Pro",
description: '精度、速度、コストのバランスが最も優れた高性能マルチモーダルモデル',
},
novaLite: {
label: 'Amazon Nova Lite',
description: '非常に低コストで高速なマルチモーダルモデルで、リアルタイム処理に最適',
},
novaMicro: {
label: 'Amazon Nova Micro',
description: '最も低いレイテンシーと低コストで提供される軽量なテキストモデル',
}
},
agent: {
label: 'エージェント',
Expand Down
Loading

0 comments on commit aabc8b6

Please sign in to comment.