Skip to content

Commit de3817d

Browse files
authored
Merge pull request #1778 from Arize-ai/main
docs: 1.2.0
2 parents 025d52b + 13b9ab0 commit de3817d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1557
-1070
lines changed

.dockerignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
docs/
2+
examples/
3+
dist/
4+
tests/
5+
integration-tests/
6+
scripts/
7+
.github
8+
.tours

CHANGELOG.md

+27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
# Changelog
22

3+
## [1.2.0](https://github.com/Arize-ai/phoenix/compare/v1.1.1...v1.2.0) (2023-11-17)
4+
5+
6+
### Features
7+
8+
* Add dockerfile ([#1761](https://github.com/Arize-ai/phoenix/issues/1761)) ([4fa8929](https://github.com/Arize-ai/phoenix/commit/4fa8929f4103e9961a8df0eb059b8df149ed648f))
9+
* **evals:** return partial results when llm function is interrupted ([#1755](https://github.com/Arize-ai/phoenix/issues/1755)) ([1fb0849](https://github.com/Arize-ai/phoenix/commit/1fb0849a4e5f39c6afc90a1417300747a0bf4bf6))
10+
* LiteLLM model support for evals ([#1675](https://github.com/Arize-ai/phoenix/issues/1675)) ([5f2a999](https://github.com/Arize-ai/phoenix/commit/5f2a9991059e060423853567a20789eba832f65a))
11+
* sagemaker nobebook support ([#1772](https://github.com/Arize-ai/phoenix/issues/1772)) ([2c0ffbc](https://github.com/Arize-ai/phoenix/commit/2c0ffbc1479ae0255b72bc2d31d5f3204fd8e32c))
12+
13+
14+
### Bug Fixes
15+
16+
* unpin llama-index version in tutorial notebooks ([#1766](https://github.com/Arize-ai/phoenix/issues/1766)) ([5ff74e3](https://github.com/Arize-ai/phoenix/commit/5ff74e3895f1b0c5642bd0897dd65e6f2913a7bd))
17+
18+
19+
### Documentation
20+
21+
* add instructions for docker build ([#1770](https://github.com/Arize-ai/phoenix/issues/1770)) ([45eb5f2](https://github.com/Arize-ai/phoenix/commit/45eb5f244997d0ff0e991879c297b564e46c9a18))
22+
23+
## [1.1.1](https://github.com/Arize-ai/phoenix/compare/v1.1.0...v1.1.1) (2023-11-16)
24+
25+
26+
### Bug Fixes
27+
28+
* update tracer for llama-index 0.9.0 ([#1750](https://github.com/Arize-ai/phoenix/issues/1750)) ([48d0996](https://github.com/Arize-ai/phoenix/commit/48d09960855d59419edfd10925aaa895fd370a0d))
29+
330
## [1.1.0](https://github.com/Arize-ai/phoenix/compare/v1.0.0...v1.1.0) (2023-11-14)
431

532

Dockerfile

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# This dockerfile is provided for convenience if you wish to run
2+
# Phoenix in a docker container / sidecar.
3+
# To use this dockerfile, you must first build the phoenix image
4+
# using the following command:
5+
# > docker build -t phoenix .
6+
# You can then run that image with the following command:
7+
# > docker run -d --name phoenix -p 6006:6006 phoenix
8+
# If you have a production use-case for phoenix, please get in touch!
9+
10+
# Use an official Python runtime as a parent image
11+
FROM python:3.10
12+
13+
# Install nodejs
14+
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
15+
RUN apt-get install -y nodejs
16+
17+
# Set the phoenix directory in the container to /phoenix
18+
WORKDIR /phoenix
19+
20+
# Add the current directory contents into the container at /phoenix
21+
ADD . /phoenix
22+
23+
# Install the app by building the typescript package
24+
RUN cd /phoenix/app && npm install && npm run build
25+
26+
# Install any needed packages
27+
RUN pip install .
28+
29+
# Make port 6006 available to the world outside this container
30+
EXPOSE 6006
31+
32+
# Run server.py when the container launches
33+
CMD ["python", "src/phoenix/server/main.py", "--host", "0.0.0.0", "--port", "6006", "serve"]

app/src/RelayEnvironment.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ import {
66
Store,
77
} from "relay-runtime";
88

9+
const graphQLPath = window.Config.basename + "/graphql";
910
/**
1011
* Relay requires developers to configure a "fetch" function that tells Relay how to load
1112
* the results of GraphQL queries from your server (or other data source). See more at
1213
* https://relay.dev/docs/en/quick-start-guide#relay-environment.
1314
*/
1415
const fetchRelay: FetchFunction = async (params, variables, _cacheConfig) => {
15-
const response = await fetch("/graphql", {
16+
const response = await fetch(graphQLPath, {
1617
method: "POST",
1718
headers: {
1819
"Content-Type": "application/json",

app/src/Routes.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ const router = createBrowserRouter(
6565
</Route>
6666
</Route>
6767
</Route>
68-
)
68+
),
69+
{
70+
basename: window.Config.basename,
71+
}
6972
);
7073

7174
export function AppRoutes() {

app/src/pages/trace/TracePage.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ function LLMMessage({ message }: { message: AttributeMessage }) {
918918
backgroundColor: "indigo-100",
919919
borderColor: "indigo-700",
920920
};
921-
} else if (role === "function") {
921+
} else if (["function", "tool"].includes(role)) {
922922
return {
923923
backgroundColor: "yellow-100",
924924
borderColor: "yellow-700",

app/src/window.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ export {};
33
declare global {
44
interface Window {
55
Config: {
6+
// basename for the app. This can be the proxy path for
7+
// Remote notebooks like SageMaker
8+
basename: string;
69
hasCorpus: boolean;
710
UMAP: {
811
minDist: number;

cspell.json

+2
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919
"NDJSON",
2020
"numpy",
2121
"openai",
22+
"openinference",
2223
"pydantic",
2324
"quickstart",
2425
"RERANKER",
2526
"respx",
2627
"rgba",
28+
"tensorboard",
2729
"tiktoken",
2830
"tracedataset",
2931
"UMAP"

docs/api/evaluation-models.md

+38-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ Here is an example of how to initialize `OpenAIModel` for Azure:
7272

7373
```python
7474
model = OpenAIModel(
75-
model = OpenAIModel(
7675
model_name="gpt-4-32k",
7776
azure_endpoint="https://YOUR_SUBDOMAIN.openai.azure.com/",
7877
api_version="2023-03-15-preview"
@@ -210,6 +209,44 @@ model = BedrockModel(client=client_bedrock)
210209

211210
```
212211

212+
213+
### phoenix.experimental.evals.LiteLLMModel
214+
Need to install the extra dependency ``litellm>=1.0.3``
215+
```python
216+
class LiteLLMModel(BaseEvalModel):
217+
model_name: str = "gpt-3.5-turbo"
218+
"""The model name to use."""
219+
temperature: float = 0.0
220+
"""What sampling temperature to use."""
221+
max_tokens: int = 256
222+
"""The maximum number of tokens to generate in the completion."""
223+
top_p: float = 1
224+
"""Total probability mass of tokens to consider at each step."""
225+
num_retries: int = 6
226+
"""Maximum number to retry a model if an RateLimitError, OpenAIError, or
227+
ServiceUnavailableError occurs."""
228+
request_timeout: int = 60
229+
"""Maximum number of seconds to wait when retrying."""
230+
model_kwargs: Dict[str, Any] = field(default_factory=dict)
231+
"""Model specific params"""
232+
233+
# non-LiteLLM params
234+
retry_min_seconds: int = 10
235+
"""Minimum number of seconds to wait when retrying."""
236+
max_content_size: Optional[int] = None
237+
"""If you're using a fine-tuned model, set this to the maximum content size"""
238+
```
239+
You can choose among [multiple models](https://docs.litellm.ai/docs/providers) supported by LiteLLM. Make sure you have set the right environment variables set prior to initializing the model. For additional information about the environment variables for specific model providers visit: [LiteLLM provider specific params](https://docs.litellm.ai/docs/completion/input#provider-specific-params)
240+
241+
Here is an example of how to initialize `LiteLLMModel` for model "gpt-3.5-turbo":
242+
243+
```python
244+
model = LiteLLMModel(model_name="gpt-3.5-turbo", temperature=0.0)
245+
model("Hello world, this is a test if you are working?")
246+
# Output: 'Hello! Yes, I am here and ready to assist you. How can I help you today?'
247+
```
248+
249+
213250
## **Usage**
214251

215252
In this section, we will showcase the methods and properties that our `EvalModels` have. First, instantiate your model from the[#supported-llm-providers](evaluation-models.md#supported-llm-providers "mention"). Once you've instantiated your `model`, you can get responses from the LLM by simply calling the model and passing a text string.

docs/llm-evals/running-pre-tested-evals/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ model("What is the largest costal city in France?")
1919

2020
We currently support a growing set of models for LLM Evals, please check out the [API section for usage](../../api/evaluation-models.md).&#x20;
2121

22-
<table data-full-width="false"><thead><tr><th width="357">Model</th><th>Support </th></tr></thead><tbody><tr><td>GPT-4 </td><td>✔</td></tr><tr><td>GPT-3.5 Turbo</td><td>✔</td></tr><tr><td>GPT-3.5 Instruct</td><td>✔</td></tr><tr><td>Azure Hosted Open AI </td><td>✔</td></tr><tr><td>Palm 2 Vertex</td><td>✔</td></tr><tr><td>AWS Bedrock</td><td>✔</td></tr><tr><td>Litellm</td><td>(coming soon)</td></tr><tr><td>Huggingface Llama7B</td><td>(coming soon)</td></tr><tr><td>Anthropic</td><td>(coming soon)</td></tr><tr><td>Cohere</td><td>(coming soon)</td></tr></tbody></table>
22+
<table data-full-width="false"><thead><tr><th width="357">Model</th><th>Support </th></tr></thead><tbody><tr><td>GPT-4 </td><td>✔</td></tr><tr><td>GPT-3.5 Turbo</td><td>✔</td></tr><tr><td>GPT-3.5 Instruct</td><td>✔</td></tr><tr><td>Azure Hosted Open AI </td><td>✔</td></tr><tr><td>Palm 2 Vertex</td><td>✔</td></tr><tr><td>AWS Bedrock</td><td>✔</td></tr><tr><td>Litellm</td><td></td></tr><tr><td>Huggingface Llama7B</td><td>(coming soon)</td></tr><tr><td>Anthropic</td><td>(coming soon)</td></tr><tr><td>Cohere</td><td>(coming soon)</td></tr></tbody></table>
2323

2424
## How we benchmark pre-tested evals&#x20;
2525

integration-tests/trace/llama_index/test_callback.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from llama_index.callbacks import CallbackManager
1212
from llama_index.embeddings.openai import OpenAIEmbedding
1313
from llama_index.graph_stores.simple import SimpleGraphStore
14-
from llama_index.indices.postprocessor.cohere_rerank import CohereRerank
14+
from llama_index.indices.postprocessor import CohereRerank
1515
from llama_index.indices.vector_store import VectorStoreIndex
1616
from llama_index.llms import OpenAI
1717
from llama_index.query_engine import RetrieverQueryEngine
@@ -180,11 +180,9 @@ def add(a: int, b: int) -> int:
180180
"temperature": 0,
181181
}
182182
assert llm_spans[0].attributes[OUTPUT_MIME_TYPE] is MimeType.JSON
183-
assert json.loads(llm_spans[0].attributes[OUTPUT_VALUE]) == {
184-
"function_call": {
185-
"name": "multiply",
186-
"arguments": '{\n "a": 2,\n "b": 3\n}',
187-
}
183+
assert json.loads(llm_spans[0].attributes[OUTPUT_VALUE])["tool_calls"][0]["function"] == {
184+
"name": "multiply",
185+
"arguments": '{\n "a": 2,\n "b": 3\n}',
188186
}
189187
assert llm_spans[0].attributes[LLM_INPUT_MESSAGES] == [
190188
{
@@ -205,7 +203,10 @@ def add(a: int, b: int) -> int:
205203
},
206204
]
207205
assert llm_spans[1].attributes[OUTPUT_MIME_TYPE] is MimeType.TEXT
208-
assert llm_spans[1].attributes[OUTPUT_VALUE] == "2 multiplied by 3 equals 6."
206+
assert llm_spans[1].attributes[OUTPUT_VALUE] in (
207+
"2 multiplied by 3 equals 6.",
208+
"2 multiplied by 3 is equal to 6.",
209+
)
209210
assert llm_spans[1].attributes.get(LLM_INPUT_MESSAGES) == [
210211
{
211212
"message.role": "user",
@@ -218,18 +219,18 @@ def add(a: int, b: int) -> int:
218219
"message.function_call_name": "multiply",
219220
},
220221
{
221-
"message.role": "function",
222+
"message.role": "tool",
222223
"message.content": "6",
223224
"message.name": "multiply",
224225
},
225226
]
226227
assert llm_spans[1].attributes[LLM_OUTPUT_MESSAGES] == [
227228
{
228-
"message.content": "2 multiplied by 3 equals 6.",
229+
"message.content": llm_spans[1].attributes[OUTPUT_VALUE],
229230
"message.role": "assistant",
230231
},
231232
{
232-
"message.content": "2 multiplied by 3 equals 6.",
233+
"message.content": llm_spans[1].attributes[OUTPUT_VALUE],
233234
"message.role": "assistant",
234235
},
235236
]

pyproject.toml

+10-3
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,16 @@ dev = [
5555
"strawberry-graphql[debug-server]==0.208.2",
5656
"pre-commit",
5757
"arize[AutoEmbeddings, LLM_Evaluation]",
58-
"llama-index>=0.8.64",
58+
"llama-index>=0.9.0",
5959
"langchain>=0.0.334",
60+
"litellm>=1.0.3"
6061
]
6162
experimental = [
6263
"tenacity",
6364
]
65+
llama-index = [
66+
"llama-index~=0.9.0",
67+
]
6468

6569
[project.urls]
6670
Documentation = "https://docs.arize.com/phoenix/"
@@ -92,7 +96,8 @@ dependencies = [
9296
"pytest-lazy-fixture",
9397
"arize",
9498
"langchain>=0.0.334",
95-
"llama-index>=0.8.63.post2",
99+
"litellm>=1.0.3",
100+
"llama-index>=0.9.0",
96101
"openai>=1.0.0",
97102
"tenacity",
98103
"nltk==3.8.1",
@@ -110,13 +115,14 @@ dependencies = [
110115
[tool.hatch.envs.type]
111116
dependencies = [
112117
"mypy==1.5.1",
113-
"llama-index>=0.8.64",
118+
"llama-index>=0.9.0",
114119
"pandas-stubs<=2.0.2.230605", # version 2.0.3.230814 is causing a dependency conflict.
115120
"types-psutil",
116121
"types-tqdm",
117122
"types-requests",
118123
"types-protobuf",
119124
"openai>=1.0.0",
125+
"litellm>=1.0.3"
120126
]
121127

122128
[tool.hatch.envs.style]
@@ -270,6 +276,7 @@ module = [
270276
"wrapt",
271277
"sortedcontainers",
272278
"langchain.*",
279+
"litellm"
273280
]
274281
ignore_missing_imports = true
275282

scripts/rag/llama_index_w_evals_and_qa.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ def df_evals(
319319
model=model,
320320
template=templates.RAG_RELEVANCY_PROMPT_TEMPLATE,
321321
rails=list(templates.RAG_RELEVANCY_PROMPT_RAILS_MAP.values()),
322-
# query_column_name="question",
322+
query_column_name="query",
323323
# document_column_name="retrieved_context_list",
324324
)
325325

src/phoenix/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from .trace.fixtures import load_example_traces
66
from .trace.trace_dataset import TraceDataset
77

8-
__version__ = "1.1.0"
8+
__version__ = "1.2.0"
99

1010
# module level doc-string
1111
__doc__ = """

src/phoenix/config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def get_running_pid() -> Optional[int]:
3939
# The host the server will run on after launch_app is called
4040
HOST = "127.0.0.1"
4141
# The port the server will run on after launch_app is called
42-
PORT = 6060
42+
PORT = 6006
4343
# The prefix of datasets that are auto-assigned a name
4444
GENERATED_DATASET_NAME_PREFIX = "phoenix_dataset_"
4545

src/phoenix/core/traces.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from typing_extensions import TypeAlias
2626
from wrapt import ObjectProxy
2727

28-
import phoenix.trace.v1.trace_pb2 as pb
28+
import phoenix.trace.v1 as pb
2929
from phoenix.datetime_utils import right_open_time_range
3030
from phoenix.trace import semantic_conventions
3131
from phoenix.trace.schemas import (
@@ -37,7 +37,9 @@
3737
SpanID,
3838
TraceID,
3939
)
40-
from phoenix.trace.v1 import decode, encode
40+
from phoenix.trace.v1.utils import decode, encode
41+
42+
END_OF_QUEUE = None # sentinel value for queue termination
4143

4244
NAME = "name"
4345
STATUS_CODE = "status_code"
@@ -112,7 +114,7 @@ class Traces:
112114
def __init__(self, spans: Optional[Iterable[Span]] = None) -> None:
113115
self._queue: "SimpleQueue[Optional[pb.Span]]" = SimpleQueue()
114116
# Putting `None` as the sentinel value for queue termination.
115-
weakref.finalize(self, self._queue.put, None)
117+
weakref.finalize(self, self._queue.put, END_OF_QUEUE)
116118
for span in spans or ():
117119
self.put(span)
118120
self._lock = RLock()
@@ -224,11 +226,9 @@ def _start_consumer(self) -> None:
224226
).start()
225227

226228
def _consume_spans(self) -> None:
227-
while True:
228-
if not (span := self._queue.get()):
229-
return
229+
while (item := self._queue.get()) is not END_OF_QUEUE:
230230
with self._lock:
231-
self._process_span(span)
231+
self._process_span(item)
232232

233233
def _process_span(self, span: pb.Span) -> None:
234234
span_id = UUID(bytes=span.context.span_id)

0 commit comments

Comments
 (0)