Skip to content

Commit 9cbee66

Browse files
committed
Update PyTorch profiler
1 parent 2729387 commit 9cbee66

26 files changed

+549
-212
lines changed

README.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
# Graphsignal: LLM Performance Analytics
1+
# Graphsignal: AI Performance Profiler
22

33
[![License](http://img.shields.io/github/license/graphsignal/graphsignal-python)](https://github.com/graphsignal/graphsignal-python/blob/main/LICENSE)
44
[![Version](https://img.shields.io/github/v/tag/graphsignal/graphsignal-python?label=version)](https://github.com/graphsignal/graphsignal-python)
55

66

7-
Graphsignal is an observability platform for AI applications. It helps developers ensure AI applications run efficiently and provide the best user experience. With Graphsignal, developers can:
7+
Graphsignal is an AI optimization platform, enabling developers to achieve faster, more efficient models and applications. With Graphsignal, developers can:
88

9-
* Measure and optimize LLM performance for APIs and hosted models.
10-
* Analyze model API costs for deployments, models, or any custom tags.
11-
* View and search LLM generations with full context.
12-
* Detect errors and monitor APIs, compute, and GPU utilization.
9+
* Identify and optimize the most significant contributors to latency.
10+
* Analyze model API costs for deployments, models, sessions, or any custom tags.
11+
* Ensure optimal model configuration and inference performance for hosted models.
12+
* Track errors and monitor APIs, compute, and GPU utilization.
1313

1414

1515
[![Dashboards](https://graphsignal.com/external/screenshot-dashboard.png)](https://graphsignal.com/)
@@ -19,7 +19,7 @@ Learn more at [graphsignal.com](https://graphsignal.com).
1919

2020
## Install
2121

22-
Install Graphsignal library.
22+
Install the Graphsignal library.
2323

2424
```bash
2525
pip install --upgrade graphsignal
@@ -38,7 +38,7 @@ graphsignal.configure(api_key='my-api-key', deployment='my-app')
3838

3939
To get an API key, sign up for a free account at [graphsignal.com](https://graphsignal.com). The key can then be found in your account's [Settings / API Keys](https://app.graphsignal.com/settings/api-keys) page.
4040

41-
Alternatively, you can add Graphsignal tracer at command line, when running your module or script. Environment variables `GRAPHSIGNAL_API_KEY` and `GRAPHSIGNAL_DEPLOYMENT` must be set.
41+
Alternatively, you can add Graphsignal tracer from the command line, when running your module or script. Environment variables `GRAPHSIGNAL_API_KEY` and `GRAPHSIGNAL_DEPLOYMENT` must be set.
4242

4343
```bash
4444
python -m graphsignal <script>
@@ -56,13 +56,14 @@ Graphsignal **auto-instruments** and traces libraries and frameworks, such as [O
5656
Refer to the guides below for detailed information on:
5757

5858
* [Manual Tracing](https://graphsignal.com/docs/guides/manual-tracing/)
59+
* [Inference Profiling](https://graphsignal.com/docs/guides/inference-profiling/)
5960
* [Session Tracking](https://graphsignal.com/docs/guides/session-tracking/)
6061
* [Cost and Usage Monitoring](https://graphsignal.com/docs/guides/cost-and-usage-monitoring/)
6162
* [Scores and Feedback](https://graphsignal.com/docs/guides/scores-and-feedback/)
6263

6364
See [API reference](https://graphsignal.com/docs/reference/python-api/) for full documentation.
6465

65-
Some integration examples are available in [examples](https://github.com/graphsignal/examples) repo.
66+
Integration examples are available in [examples](https://github.com/graphsignal/examples) repository.
6667

6768

6869
## Analyze
@@ -72,18 +73,18 @@ Some integration examples are available in [examples](https://github.com/graphsi
7273

7374
## Overhead
7475

75-
Graphsignal tracer is very lightweight. The overhead per trace is measured to be less than 100 microseconds.
76+
Graphsignal tracer is highly lightweight. The overhead per trace is measured to be less than 100 microseconds.
7677

7778

7879
## Security and Privacy
7980

80-
Graphsignal tracer can only open outbound connections to `api.graphsignal.com` and send data, no inbound connections or commands are possible.
81+
The Graphsignal tracer only establishes outbound connections to `api.graphsignal.com` to send data; inbound connections or commands are not possible.
8182

8283
Payloads, such as prompts and completions, are recorded by default in case of automatic tracing. To disable, set `record_payloads=False` in `graphsignal.configure`.
8384

8485

8586
## Troubleshooting
8687

87-
To enable debug logging, add `debug_mode=True` to `configure()`. If the debug log doesn't give you any hints on how to fix a problem, please report it to our support team via your account.
88+
To enable debug logging, add `debug_mode=True` to `configure()`. If the debug log doesn’t provide hints for resolving the issue, report it to our support team via your account.
8889

8990
In case of connection issues, please make sure outgoing connections to `https://api.graphsignal.com` are allowed.

graphsignal/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def configure(
5959
tags: Optional[Dict[str, str]] = None,
6060
auto_instrument: Optional[bool] = True,
6161
record_payloads: Optional[bool] = True,
62+
profiling_rate: Optional[float] = 0.1,
6263
upload_on_shutdown: Optional[bool] = True,
6364
debug_mode: Optional[bool] = False) -> None:
6465
global _tracer
@@ -80,6 +81,7 @@ def configure(
8081
tags=tags,
8182
auto_instrument=auto_instrument,
8283
record_payloads=record_payloads,
84+
profiling_rate=profiling_rate,
8385
upload_on_shutdown=upload_on_shutdown,
8486
debug_mode=debug_mode)
8587
_tracer.setup()
@@ -121,18 +123,20 @@ def remove_context_tag(key: str):
121123

122124
def trace(
123125
operation: str,
124-
tags: Optional[Dict[str, str]] = None) -> 'Span':
126+
tags: Optional[Dict[str, str]] = None,
127+
with_profile: Optional[bool] = False) -> 'Span':
125128
_check_configured()
126129

127-
return _tracer.trace(operation=operation, tags=tags)
130+
return _tracer.trace(operation=operation, tags=tags, with_profile=with_profile)
128131

129132

130133
def trace_function(
131134
func=None,
132135
*,
133136
operation: Optional[str] = None,
134-
tags: Optional[Dict[str, str]] = None):
135-
return _tracer.trace_function(func, operation=operation, tags=tags)
137+
tags: Optional[Dict[str, str]] = None,
138+
with_profile: Optional[bool] = False) -> Any:
139+
return _tracer.trace_function(func, operation=operation, tags=tags, with_profile=with_profile)
136140

137141

138142
def score(

graphsignal/client/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from graphsignal.client.models.metric import Metric
3939
from graphsignal.client.models.metric_type import MetricType
4040
from graphsignal.client.models.payload import Payload
41+
from graphsignal.client.models.profile import Profile
4142
from graphsignal.client.models.rate import Rate
4243
from graphsignal.client.models.score import Score
4344
from graphsignal.client.models.score_query_result import ScoreQueryResult

graphsignal/client/api/default_api.py

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
from datetime import datetime
2020
from pydantic import Field, StrictInt, StrictStr
21-
from typing import List, Optional
21+
from typing import Any, Dict, List, Optional
2222
from typing_extensions import Annotated
2323
from graphsignal.client.models.log_entry import LogEntry
2424
from graphsignal.client.models.metric import Metric
@@ -354,7 +354,9 @@ def _query_scores_serialize(
354354
_query_params: List[Tuple[str, str]] = []
355355
_header_params: Dict[str, Optional[str]] = _headers or {}
356356
_form_params: List[Tuple[str, str]] = []
357-
_files: Dict[str, str] = {}
357+
_files: Dict[
358+
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
359+
] = {}
358360
_body_params: Optional[bytes] = None
359361

360362
# process the path parameters
@@ -415,11 +417,12 @@ def _query_scores_serialize(
415417

416418

417419
# set the HTTP header `Accept`
418-
_header_params['Accept'] = self.api_client.select_header_accept(
419-
[
420-
'application/json'
421-
]
422-
)
420+
if 'Accept' not in _header_params:
421+
_header_params['Accept'] = self.api_client.select_header_accept(
422+
[
423+
'application/json'
424+
]
425+
)
423426

424427

425428
# authentication setting
@@ -728,7 +731,9 @@ def _query_spans_serialize(
728731
_query_params: List[Tuple[str, str]] = []
729732
_header_params: Dict[str, Optional[str]] = _headers or {}
730733
_form_params: List[Tuple[str, str]] = []
731-
_files: Dict[str, str] = {}
734+
_files: Dict[
735+
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
736+
] = {}
732737
_body_params: Optional[bytes] = None
733738

734739
# process the path parameters
@@ -781,11 +786,12 @@ def _query_spans_serialize(
781786

782787

783788
# set the HTTP header `Accept`
784-
_header_params['Accept'] = self.api_client.select_header_accept(
785-
[
786-
'application/json'
787-
]
788-
)
789+
if 'Accept' not in _header_params:
790+
_header_params['Accept'] = self.api_client.select_header_accept(
791+
[
792+
'application/json'
793+
]
794+
)
789795

790796

791797
# authentication setting
@@ -1030,7 +1036,9 @@ def _upload_logs_serialize(
10301036
_query_params: List[Tuple[str, str]] = []
10311037
_header_params: Dict[str, Optional[str]] = _headers or {}
10321038
_form_params: List[Tuple[str, str]] = []
1033-
_files: Dict[str, str] = {}
1039+
_files: Dict[
1040+
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
1041+
] = {}
10341042
_body_params: Optional[bytes] = None
10351043

10361044
# process the path parameters
@@ -1043,11 +1051,12 @@ def _upload_logs_serialize(
10431051

10441052

10451053
# set the HTTP header `Accept`
1046-
_header_params['Accept'] = self.api_client.select_header_accept(
1047-
[
1048-
'application/json'
1049-
]
1050-
)
1054+
if 'Accept' not in _header_params:
1055+
_header_params['Accept'] = self.api_client.select_header_accept(
1056+
[
1057+
'application/json'
1058+
]
1059+
)
10511060

10521061
# set the HTTP header `Content-Type`
10531062
if _content_type:
@@ -1305,7 +1314,9 @@ def _upload_metrics_serialize(
13051314
_query_params: List[Tuple[str, str]] = []
13061315
_header_params: Dict[str, Optional[str]] = _headers or {}
13071316
_form_params: List[Tuple[str, str]] = []
1308-
_files: Dict[str, str] = {}
1317+
_files: Dict[
1318+
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
1319+
] = {}
13091320
_body_params: Optional[bytes] = None
13101321

13111322
# process the path parameters
@@ -1318,11 +1329,12 @@ def _upload_metrics_serialize(
13181329

13191330

13201331
# set the HTTP header `Accept`
1321-
_header_params['Accept'] = self.api_client.select_header_accept(
1322-
[
1323-
'application/json'
1324-
]
1325-
)
1332+
if 'Accept' not in _header_params:
1333+
_header_params['Accept'] = self.api_client.select_header_accept(
1334+
[
1335+
'application/json'
1336+
]
1337+
)
13261338

13271339
# set the HTTP header `Content-Type`
13281340
if _content_type:
@@ -1580,7 +1592,9 @@ def _upload_scores_serialize(
15801592
_query_params: List[Tuple[str, str]] = []
15811593
_header_params: Dict[str, Optional[str]] = _headers or {}
15821594
_form_params: List[Tuple[str, str]] = []
1583-
_files: Dict[str, str] = {}
1595+
_files: Dict[
1596+
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
1597+
] = {}
15841598
_body_params: Optional[bytes] = None
15851599

15861600
# process the path parameters
@@ -1593,11 +1607,12 @@ def _upload_scores_serialize(
15931607

15941608

15951609
# set the HTTP header `Accept`
1596-
_header_params['Accept'] = self.api_client.select_header_accept(
1597-
[
1598-
'application/json'
1599-
]
1600-
)
1610+
if 'Accept' not in _header_params:
1611+
_header_params['Accept'] = self.api_client.select_header_accept(
1612+
[
1613+
'application/json'
1614+
]
1615+
)
16011616

16021617
# set the HTTP header `Content-Type`
16031618
if _content_type:
@@ -1855,7 +1870,9 @@ def _upload_spans_serialize(
18551870
_query_params: List[Tuple[str, str]] = []
18561871
_header_params: Dict[str, Optional[str]] = _headers or {}
18571872
_form_params: List[Tuple[str, str]] = []
1858-
_files: Dict[str, str] = {}
1873+
_files: Dict[
1874+
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
1875+
] = {}
18591876
_body_params: Optional[bytes] = None
18601877

18611878
# process the path parameters
@@ -1868,11 +1885,12 @@ def _upload_spans_serialize(
18681885

18691886

18701887
# set the HTTP header `Accept`
1871-
_header_params['Accept'] = self.api_client.select_header_accept(
1872-
[
1873-
'application/json'
1874-
]
1875-
)
1888+
if 'Accept' not in _header_params:
1889+
_header_params['Accept'] = self.api_client.select_header_accept(
1890+
[
1891+
'application/json'
1892+
]
1893+
)
18761894

18771895
# set the HTTP header `Content-Type`
18781896
if _content_type:

0 commit comments

Comments
 (0)