Skip to content

Commit

Permalink
chore(weave): Pre-release doc script audit (#1476)
Browse files Browse the repository at this point in the history
* init

* subtle fixes

* minor style

* give all example projects the same name

* fix for model_output

* a few more inits

* a few more inits

* added tuts

* linted

* fixed name
  • Loading branch information
tssweeney authored Apr 4, 2024
1 parent 313cba7 commit f92b480
Show file tree
Hide file tree
Showing 20 changed files with 432 additions and 25 deletions.
1 change: 1 addition & 0 deletions docs/docs/guides/core-types/datasets.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ hide_table_of_contents: true
Easily update datasets with the UI and download the latest version locally with a simple API.

This guide will show you how to:

- Publish `Dataset`s to W&B
- Download the latest version
- Iterate over examples
Expand Down
12 changes: 8 additions & 4 deletions docs/docs/guides/core-types/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ hide_table_of_contents: true
A `Model` is a combination of data (which can include configuration, trained model weights, or other information) and code that defines how the model operates. By structuring your code to be compatible with this API, you benefit from a structured way to version your application so you can more systematically keep track of your experiments.

To create a model in Weave, you need the following:

- a class that inherits from `weave.Model`
- type definitions on all attributes
- a typed `predict` function with `@weave.op()` decorator
Expand All @@ -28,9 +29,10 @@ class YourModel(Model):
```

You can call the model as usual with:

```python
import weave
weave.init('project-name')
weave.init('intro-example')

model = YourModel(attribute1='hello', attribute2=5)
model.predict('world')
Expand All @@ -41,12 +43,13 @@ This will track the model settings along with the inputs and outputs anytime you
## Automatic versioning of models

When you change the attributes or the code that defines your model, these changes will be logged and the version will be updated.
This ensures that you can compare the predictions across different versions of your model. Use this to iterate on prompts or to try the latest LLM and compare predictions across different settings.
This ensures that you can compare the predictions across different versions of your model. Use this to iterate on prompts or to try the latest LLM and compare predictions across different settings.

For example, here we create a new model:

```python
import weave
weave.init('project-name')
weave.init('intro-example')

model = YourModel(attribute1='howdy', attribute2=10)
model.predict('world')
Expand All @@ -57,6 +60,7 @@ After calling this, you will see that you now have two versions of this Model in
## Serve models

To serve a model, you can easily spin up a FastAPI server by calling:

```bash
weave serve <your model ref>
```
Expand All @@ -65,7 +69,7 @@ For additional instructions, see [serve](/guides/tools/serve).

## Track production calls

To separate production calls, you can add an additional attribute to the predictions for easy filtering in the UI or API.
To separate production calls, you can add an additional attribute to the predictions for easy filtering in the UI or API.

```python
with weave.attributes({'env': 'production'}):
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/guides/tools/serve.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Given a Weave ref to any Weave Model you can run:
weave serve <ref>
```

to run a FastAPI server for that model.
to run a FastAPI server for that model. Visit [http://0.0.0.0:9996/docs](http://0.0.0.0:9996/docs) to query the model interactively.

## Install FastAPI

Expand All @@ -22,6 +22,7 @@ pip install fastapi uvicorn
## Serve Model

In a terminal, call:

```bash
weave serve <your model ref>
```
Expand All @@ -30,4 +31,3 @@ Get your model ref by navigating to the model and copying it from the UI. It sho
`weave:///your_entity/project-name/YourModel:<hash>`

To use it, navigate to the Swagger UI link, click the predict endpoint and then click "Try it out!".

18 changes: 9 additions & 9 deletions docs/docs/guides/tracking/objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ Weave's serialization layer saves and versions Python objects.
## Publishing an object

```python
# Initialize tracking to the project 'cat-project'
weave.init('cat-project')
import weave
# Initialize tracking to the project 'intro-example'
weave.init('intro-example')
# Save a list, giving it the name 'cat-names'
weave.publish(['felix', 'jimbo', 'billie'], 'cat-names')
```
Expand All @@ -23,8 +24,9 @@ Saving an object with a name will create the first version of that object if it
`weave.publish` returns a Ref. You can call `.get()` on any Ref to get the object back.

You can construct a ref and then fetch the object back.

```python
weave.init('cat-project')
weave.init('intro-example')
cat_names = weave.ref('cat-names').get()
```

Expand All @@ -36,19 +38,17 @@ A fully qualified weave object ref uri looks like this:
weave:///<entity>/<project>/object/<object_name>:<object_version>
```

- *entity*: wandb entity (username or team)
- *project*: wandb project
- *object_name*: object name
- *object_version*: either a version hash, a string like v0, v1..., or an alias like ":latest". All objects have the ":latest" alias.

- _entity_: wandb entity (username or team)
- _project_: wandb project
- _object_name_: object name
- _object_version_: either a version hash, a string like v0, v1..., or an alias like ":latest". All objects have the ":latest" alias.

Refs can be constructed with a few different styles

- `weave.ref(<name>)`: requires `weave.init(<project>)` to have been called. Refers to the ":latest" version
- `weave.ref(<name>:<version>)`: requires `weave.init(<project>)` to have been called.
- `weave.ref(<fully_qualified_ref_uri>)`: can be constructed without calling weave.init


## TODO

- iterating through other versions of an object
Expand Down
4 changes: 3 additions & 1 deletion docs/docs/guides/tracking/ops.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ A Weave op is a versioned function that automatically logs all calls.
To create an op, decorate a python function with `weave.op()`

```python
import weave

@weave.op()
def track_me(v):
return v + 5

weave.init('add5-GPT')
weave.init('intro-example')
track_me(15)
```

Expand Down
4 changes: 2 additions & 2 deletions docs/docs/guides/tracking/tracing.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ def pokedex(name: str, prompt: str) -> str:
return response.choices[0].message.content

# highlight-next-line
weave.init('pokedex')
weave.init('intro-example')
# Get data for a specific Pokémon
pokemon_data = pokedex(random.choice(POKEMON), PROMPT)
```

## Add additional attributes

When calling tracked functions, you can add additional metadata to the call by using the `weave.attributes` context manager.
When calling tracked functions, you can add additional metadata to the call by using the `weave.attributes` context manager.

For example, you can add a `user_id` to each call and then filter calls by user. In the example below, any function called within the context manager will have the `user_id` attribute set to `lukas` and `env` attribute set to `production`.

Expand Down
2 changes: 0 additions & 2 deletions docs/docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ hide_table_of_contents: true

# Introduction

*🍲 This version of Weave is pre-release software. 🍲*

Weave is a toolkit for developing Generative AI applications, built by [Weights & Biases](https://wandb.ai).

Our goal is to bring rigor, best-practices, and composability to the inherently experimental process of developing Generative AI software, without introducing cognitive overhead.
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ sentence = "There are many fruits that were found on the recently discovered pla
extract_fruit(sentence)
```

Now, every time you call this function, weave will automatically capture the input & output data and log any changes to the code.
Now, every time you call this function, weave will automatically capture the input & output data and log any changes to the code.
Run this application and your console will output a link to view it within W&B.

:::note
Expand Down
15 changes: 11 additions & 4 deletions docs/docs/tutorial-eval.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ class ExtractFruitsModel(weave.Model):
You can instantiate `Model` objects as normal like this:

```python
import asyncio
import weave

weave.init('intro-example')

model = ExtractFruitsModel(model_name='gpt-3.5-turbo-1106',
prompt_template='Extract fields ("fruit": <str>, "color": <str>, "flavor": <str>) from the following text, as json: {sentence}')
sentence = "There are many fruits that were found on the recently discovered planet Goocrux. There are neoskizzles that grow there, which are purple and taste like candy."
Expand Down Expand Up @@ -94,9 +99,11 @@ Here `sentence` is passed to the model's predict function, and `target` is used
import weave
from weave.flow.scorer import MultiTaskBinaryClassificationF1

weave.init('intro-example')

@weave.op()
def fruit_name_score(target: dict, prediction: dict) -> dict:
return {'correct': target['fruit'] == prediction['fruit']}
def fruit_name_score(target: dict, model_output: dict) -> dict:
return {'correct': target['fruit'] == model_output['fruit']}

# highlight-next-line
evaluation = weave.Evaluation(
Expand Down Expand Up @@ -173,8 +180,8 @@ examples = [

# We define a scoring functions to compare our model predictions with a ground truth label.
@weave.op()
def fruit_name_score(target: dict, prediction: dict) -> dict:
return {'correct': target['fruit'] == prediction['fruit']}
def fruit_name_score(target: dict, model_output: dict) -> dict:
return {'correct': target['fruit'] == model_output['fruit']}

# Finally, we run an evaluation of this model.
# This will generate a prediction for each input example, and then score it with each scoring function.
Expand Down
28 changes: 28 additions & 0 deletions tutorial_scripts/01_quickstart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import weave
import json
from openai import OpenAI


@weave.op()
def extract_fruit(sentence: str) -> dict:
client = OpenAI()

response = client.chat.completions.create(
model="gpt-3.5-turbo-1106",
messages=[
{
"role": "system",
"content": "You will be provided with unstructured data, and your task is to parse it one JSON dictionary with fruit, color and flavor as keys.",
},
{"role": "user", "content": sentence},
],
temperature=0.7,
response_format={"type": "json_object"},
)
extracted = response.choices[0].message.content
return json.loads(extracted)


weave.init("intro-example")
sentence = "There are many fruits that were found on the recently discovered planet Goocrux. There are neoskizzles that grow there, which are purple and taste like candy."
extract_fruit(sentence)
28 changes: 28 additions & 0 deletions tutorial_scripts/02_in_app_quickstart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import weave
import json
from openai import OpenAI


@weave.op() # 🐝
def extract_fruit(sentence: str) -> dict:
client = OpenAI()

response = client.chat.completions.create(
model="gpt-3.5-turbo-1106",
messages=[
{
"role": "system",
"content": "You will be provided with unstructured data, and your task is to parse it one JSON dictionary with fruit, color and flavor as keys.",
},
{"role": "user", "content": sentence},
],
temperature=0.7,
response_format={"type": "json_object"},
)
extracted = response.choices[0].message.content
return json.loads(extracted)


weave.init("intro-example") # 🐝
sentence = "There are many fruits that were found on the recently discovered planet Goocrux. There are neoskizzles that grow there, which are purple and taste like candy."
extract_fruit(sentence)
32 changes: 32 additions & 0 deletions tutorial_scripts/03_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from weave import Model
import weave


class YourModel(Model):
attribute1: str
attribute2: int

@weave.op()
def predict(self, input_data: str) -> dict:
# Model logic goes here
prediction = self.attribute1 + " " + input_data
return {"pred": prediction}


import weave

weave.init("intro-example")

model = YourModel(attribute1="hello", attribute2=5)
model.predict("world")

import weave

weave.init("intro-example")

model = YourModel(attribute1="howdy", attribute2=10)
model.predict("world")


with weave.attributes({"env": "production"}):
model.predict("world")
36 changes: 36 additions & 0 deletions tutorial_scripts/04_datasets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import weave
from weave import Dataset

# Initialize Weave
weave.init("intro-example")

# Create a dataset
dataset = Dataset(
name="grammar",
rows=[
{
"id": "0",
"sentence": "He no likes ice cream.",
"correction": "He doesn't like ice cream.",
},
{
"id": "1",
"sentence": "She goed to the store.",
"correction": "She went to the store.",
},
{
"id": "2",
"sentence": "They plays video games all day.",
"correction": "They play video games all day.",
},
],
)

# Publish the dataset
weave.publish(dataset)

# Retrieve the dataset
dataset_ref = weave.ref("grammar").get()

# Access a specific example
example_label = dataset_ref.rows[2]["sentence"]
Loading

0 comments on commit f92b480

Please sign in to comment.