Skip to content

Commit

Permalink
Merge branch 'master' into feat/huggingface-inference
Browse files Browse the repository at this point in the history
  • Loading branch information
soumik12345 authored Jan 22, 2025
2 parents cb0c748 + 212bf14 commit 1866ba8
Show file tree
Hide file tree
Showing 41 changed files with 1,403 additions and 164 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ jobs:
"trace",
"trace_server",
"anthropic",
"bedrock",
"cerebras",
"cohere",
"dspy",
Expand Down
137 changes: 137 additions & 0 deletions docs/docs/guides/integrations/bedrock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Amazon Bedrock

Weave automatically tracks and logs LLM calls made via Amazon Bedrock, AWS's fully managed service that offers foundation models from leading AI companies through a unified API.

## Traces

Weave will automatically capture traces for Bedrock API calls. You can use the Bedrock client as usual after initializing Weave and patching the client:

```python
import weave
import boto3
import json
from weave.integrations.bedrock.bedrock_sdk import patch_client

weave.init("my_bedrock_app")

# Create and patch the Bedrock client
client = boto3.client("bedrock-runtime")
patch_client(client)

# Use the client as usual
response = client.invoke_model(
modelId="anthropic.claude-3-5-sonnet-20240620-v1:0",
body=json.dumps({
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 100,
"messages": [
{"role": "user", "content": "What is the capital of France?"}
]
}),
contentType='application/json',
accept='application/json'
)
response_dict = json.loads(response.get('body').read())
print(response_dict["content"][0]["text"])
```

of using the `converse` API:

```python
messages = [{"role": "user", "content": [{"text": "What is the capital of France?"}]}]

response = client.converse(
modelId="anthropic.claude-3-5-sonnet-20240620-v1:0",
system=[{"text": "You are a helpful AI assistant."}],
messages=messages,
inferenceConfig={"maxTokens": 100},
)
print(response["output"]["message"]["content"][0]["text"])

```

## Wrapping with your own ops

You can create reusable operations using the `@weave.op()` decorator. Here's an example showing both the `invoke_model` and `converse` APIs:

```python
@weave.op
def call_model_invoke(
model_id: str,
prompt: str,
max_tokens: int = 100,
temperature: float = 0.7
) -> dict:
body = json.dumps({
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": max_tokens,
"temperature": temperature,
"messages": [
{"role": "user", "content": prompt}
]
})

response = client.invoke_model(
modelId=model_id,
body=body,
contentType='application/json',
accept='application/json'
)
return json.loads(response.get('body').read())

@weave.op
def call_model_converse(
model_id: str,
messages: str,
system_message: str,
max_tokens: int = 100,
) -> dict:
response = client.converse(
modelId=model_id,
system=[{"text": system_message}],
messages=messages,
inferenceConfig={"maxTokens": max_tokens},
)
return response
```

![](./imgs/bedrock_converse.png)

## Create a `Model` for easier experimentation

You can create a Weave Model to better organize your experiments and capture parameters. Here's an example using the `converse` API:

```python
class BedrockLLM(weave.Model):
model_id: str
max_tokens: int = 100
system_message: str = "You are a helpful AI assistant."

@weave.op
def predict(self, prompt: str) -> str:
"Generate a response using Bedrock's converse API"

messages = [{
"role": "user",
"content": [{"text": prompt}]
}]

response = client.converse(
modelId=self.model_id,
system=[{"text": self.system_message}],
messages=messages,
inferenceConfig={"maxTokens": self.max_tokens},
)
return response["output"]["message"]["content"][0]["text"]

# Create and use the model
model = BedrockLLM(
model_id="anthropic.claude-3-5-sonnet-20240620-v1:0",
max_tokens=100,
system_message="You are an expert software engineer that knows a lot of programming. You prefer short answers."
)
result = model.predict("What is the best way to handle errors in Python?")
print(result)
```

This approach allows you to version your experiments and easily track different configurations of your Bedrock-based application.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions docs/docs/guides/tracking/objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,28 @@ Saving an object with a name will create the first version of that object if it
</TabItem>
</Tabs>

## Deleting an object

<Tabs groupId="programming-language" queryString>
<TabItem value="python" label="Python" default>
To delete a version of an object, call `.delete()` on the object ref.

```python
weave.init('intro-example')
cat_names_ref = weave.ref('cat-names:v1')
cat_names_ref.delete()
```

Trying to access a deleted object will result in an error. Resolving an object that has a reference to a deleted object will return a `DeletedRef` object in place of the deleted object.

</TabItem>
<TabItem value="typescript" label="TypeScript">
```plaintext
This feature is not available in TypeScript yet. Stay tuned!
```
</TabItem>
</Tabs>

## Ref styles

A fully qualified weave object ref uri looks like this:
Expand Down
22 changes: 22 additions & 0 deletions docs/docs/guides/tracking/ops.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,25 @@ If you want to suppress the printing of call links during logging, you can set t
```bash
export WEAVE_PRINT_CALL_LINK=false
```

## Deleting an op

<Tabs groupId="programming-language" queryString>
<TabItem value="python" label="Python" default>
To delete a version of an op, call `.delete()` on the op ref.

```python
weave.init('intro-example')
my_op_ref = weave.ref('track_me:v1')
my_op_ref.delete()
```

Trying to access a deleted op will result in an error.

</TabItem>
<TabItem value="typescript" label="TypeScript">
```plaintext
This feature is not available in TypeScript yet. Stay tuned!
```
</TabItem>
</Tabs>
73 changes: 62 additions & 11 deletions docs/docs/guides/tracking/tracing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import TracingCallsMacroImage from '@site/static/img/screenshots/calls_macro.png
import TracingCallsFilterImage from '@site/static/img/screenshots/calls_filter.png';
import BasicCallImage from '@site/static/img/screenshots/basic_call.png';


# Calls

<DesktopWindow
Expand Down Expand Up @@ -699,17 +700,7 @@ The easiest way to get started is to construct a view in the UI, then learn more
:::info[Comming Soon]
::: */}

## Call FAQ

{/* TODO:
Common Questions / Variations:
* Images
* Ops
* Cost?
* General data model
*/}

#### Call Schema
### Call Schema

Please see the [schema](../../reference/python-sdk/weave/trace_server/weave.trace_server.trace_server_interface#class-callschema) for a complete list of fields.

Expand Down Expand Up @@ -748,4 +739,64 @@ Calculated Fields:
* Duration
* Status

## FAQs

### How do I disable tracing?

**Environment Variable:**

In situations where you want to unconditionally disable tracing for the entire program, you can set the environment variable `WEAVE_DISABLED=true`.

**Client Initialization:**

Sometimes, you may want to conditionally enable tracing for a specific initialization based on some condition. In this case, you can initialize the client with the `disabled` flag in init settings.

```python
import weave

# Initialize the client
client = weave.init(..., settings={"disabled": True})
```

**Context Manager:**

Finally, you may want to conditionally disable tracing for a single function based on some application logic. In this case, you can use the context manager `with set_tracing_enabled(False)` which can be imported from `weave.trace.context.call_context`.

```python
import weave
from weave.trace.context.call_context import set_tracing_enabled

client = weave.init(...)

@weave.op
def my_op():
...

with set_tracing_enabled(False):
my_op()
```

### How do I capture information about a call?

Typically you would call an op directly:

```python
@weave.op
def my_op():
...

my_op()
```

However, you can also get access to the call object directly by invoking the `call` method on the op:

```python
@weave.op
def my_op():
...

output, call = my_op.call()
```

From here, the `call` object will have all the information about the call, including the inputs, outputs, and other metadata.

1 change: 1 addition & 0 deletions docs/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ const sidebars: SidebarsConfig = {
"guides/integrations/cohere",
"guides/integrations/mistral",
"guides/integrations/azure",
"guides/integrations/bedrock",
"guides/integrations/google-gemini",
"guides/integrations/together_ai",
"guides/integrations/groq",
Expand Down
2 changes: 2 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"litellm",
"notdiamond",
"google_ai_studio",
"bedrock",
"scorers_tests",
]

Expand Down Expand Up @@ -50,6 +51,7 @@ def lint(session):
"notdiamond",
"openai",
"vertexai",
"bedrock",
"scorers_tests",
"pandas-test",
"huggingface",
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ pandas-test = ["pandas>=2.2.3"]
modal = ["modal", "python-dotenv"]
huggingface = ["huggingface-hub>=0.26.2"]
vertexai = ["vertexai>=1.70.0"]
bedrock = ["boto3", "moto[bedrock]>=5.0.24"]
test = [
"nox",
"pytest>=8.2.0",
Expand Down Expand Up @@ -230,7 +231,7 @@ module = "weave_query.*"
ignore_errors = true

[tool.bumpversion]
current_version = "0.51.29-dev0"
current_version = "0.51.30-dev0"
parse = """(?x)
(?P<major>0|[1-9]\\d*)\\.
(?P<minor>0|[1-9]\\d*)\\.
Expand Down
Loading

0 comments on commit 1866ba8

Please sign in to comment.