ChatGPT 现在非常火爆,它已经让互联网崩溃了。作为 ChatGPT 的忠实用户和 ChatGPT 应用程序的开发者,我对这项技术的可能性感到非常兴奋。我看到的情况是,基于 ChatGPT 的解决方案将呈指数级增长,人们将需要监控这些解决方案。
由于这是一项相当新的技术,我们不希望用专有技术来给我们的闪亮新代码增加负担,对吧?当然不希望,这就是为什么我们将在本博客中使用 OpenTelemetry 来监控我们的 ChatGPT 代码。这对我来说尤其重要,因为我最近创建了一个从 Zoom 通话生成会议记录的服务。如果我要将此服务发布到公共领域,它会花费我多少钱,以及我如何确保它可用?
OpenAI API 来解救
毫无疑问,OpenAI API 非常棒。它还在每个 API 调用的每个响应中为我们提供了如下信息,这可以帮助我们了解自己的收费情况。通过使用令牌计数、模型以及 OpenAI 在其网站上公布的价格,我们可以计算出成本。问题是,我们如何将这些信息获取到我们的监控工具中?
{
"choices": [
{
"finish_reason": "length",
"index": 0,
"logprobs": null,
"text": "\n\nElastic is an amazing observability tool because it provides a comprehensive set of features for monitoring"
}
],
"created": 1680281710,
"id": "cmpl-70CJq07gibupTcSM8xOWekOTV5FRF",
"model": "text-davinci-003",
"object": "text_completion",
"usage": {
"completion_tokens": 20,
"prompt_tokens": 9,
"total_tokens": 29
}
}
OpenTelemetry 来解救
OpenTelemetry 真的是一个非常出色的作品。多年来,它得到了如此多的采用和投入,似乎真的已经到了我们可以称之为可观测性的 Linux 的地步。我们可以使用它来记录日志、指标和跟踪,并以厂商中立的方式将其导入我们最喜欢的可观测性工具 — 在本例中为 Elastic Observability。
借助 Python 中最新最好的 otel 库,我们可以自动检测外部调用,这将帮助我们了解 OpenAI 调用的性能。让我们先来看看我们的示例 Python 应用程序,它实现了 Flask 和 ChatGPT API,并且还具有 OpenTelemetry。如果您想自己尝试一下,请查看本博客末尾的 GitHub 链接并按照以下步骤操作。
设置 Elastic Cloud 帐户(如果您还没有帐户)
- 在 https://elastic.ac.cn/cloud/elasticsearch-service/signup 注册为期两周的免费试用。
- 创建部署。
登录后,单击添加集成。
单击 APM 集成。
然后向下滚动以获取本博客所需的详细信息
请务必设置以下环境变量,将变量替换为您从上面 Elastic 获取的数据,以及从 此处 获取的 OpenAI 数据,然后在命令行上运行这些导出命令。
export OPEN_AI_KEY=sk-abcdefgh5ijk2l173mnop3qrstuvwxyzab2cde47fP2g9jij
export OTEL_EXPORTER_OTLP_AUTH_HEADER=abc9ldeofghij3klmn
export OTEL_EXPORTER_OTLP_ENDPOINT=https://123456abcdef.apm.us-west2.gcp.elastic-cloud.com:443
并安装以下 Python 库
pip3 install opentelemetry-api
pip3 install opentelemetry-sdk
pip3 install opentelemetry-exporter-otlp
pip3 install opentelemetry-instrumentation
pip3 install opentelemetry-instrumentation-requests
pip3 install openai
pip3 install flask
以下是我们用于示例应用程序的代码。在现实世界中,这应该是您自己的代码。它所做的就是使用以下消息调用 OpenAI API:“为什么 Elastic 是一款出色的可观测性工具?”
import openai
from flask import Flask
import monitor # Import the module
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
import urllib
import os
from opentelemetry import trace
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
# OpenTelemetry setup up code here, feel free to replace the “your-service-name” attribute here.
resource = Resource(attributes={
SERVICE_NAME: "your-service-name"
})
provider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint=os.getenv('OTEL_EXPORTER_OTLP_ENDPOINT'),
headers="Authorization=Bearer%20"+os.getenv('OTEL_EXPORTER_OTLP_AUTH_HEADER')))
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)
RequestsInstrumentor().instrument()
# Initialize Flask app and instrument it
app = Flask(__name__)
# Set OpenAI API key
openai.api_key = os.getenv('OPEN_AI_KEY')
@app.route("/completion")
@tracer.start_as_current_span("do_work")
def completion():
response = openai.Completion.create(
model="text-davinci-003",
prompt="Why is Elastic an amazing observability tool?",
max_tokens=20,
temperature=0
)
return response.choices[0].text.strip()
if __name__ == "__main__":
app.run()
任何在这里使用 Python 实现 OpenTelemetry 的人都应该非常熟悉此代码 — 没有什么特别的魔法。魔法发生在您可以自由使用来检测自己的 OpenAI 应用程序的“monitor”代码中。
捣鼓
在 monitor.py 代码中,您会看到我们做了一些称为“Monkey Patching”的事情。Monkey patching 是 Python 中的一种技术,通过修改其属性或方法来动态修改类或模块在运行时的行为。Monkey patching 允许您更改类或模块的功能,而无需修改其源代码。当您需要修改现有类或模块的行为,而您无法控制或无法直接修改时,它会很有用。
我们在这里要做的是修改“Completion”调用的行为,以便我们可以窃取响应指标并将它们添加到我们的 OpenTelemetry span 中。您可以在下面看到我们是如何做的
def count_completion_requests_and_tokens(func):
@wraps(func)
def wrapper(*args, **kwargs):
counters['completion_count'] += 1
response = func(*args, **kwargs)
token_count = response.usage.total_tokens
prompt_tokens = response.usage.prompt_tokens
completion_tokens = response.usage.completion_tokens
cost = calculate_cost(response)
strResponse = json.dumps(response)
# Set OpenTelemetry attributes
span = trace.get_current_span()
if span:
span.set_attribute("completion_count", counters['completion_count'])
span.set_attribute("token_count", token_count)
span.set_attribute("prompt_tokens", prompt_tokens)
span.set_attribute("completion_tokens", completion_tokens)
span.set_attribute("model", response.model)
span.set_attribute("cost", cost)
span.set_attribute("response", strResponse)
return response
return wrapper
# Monkey-patch the openai.Completion.create function
openai.Completion.create = count_completion_requests_and_tokens(openai.Completion.create)
通过将所有这些数据添加到我们的 Span 中,我们可以实际将其发送到我们的 OpenTelemetry OTLP 端点(在本例中,它将是 Elastic)。这样做的好处是,您可以轻松地使用这些数据进行搜索或构建仪表板和可视化效果。在最后一步中,我们还要计算成本。我们通过实现以下函数来完成此操作,该函数将计算对 OpenAI API 的单个请求的成本。
def calculate_cost(response):
if response.model in ['gpt-4', 'gpt-4-0314']:
cost = (response.usage.prompt_tokens * 0.03 + response.usage.completion_tokens * 0.06) / 1000
elif response.model in ['gpt-4-32k', 'gpt-4-32k-0314']:
cost = (response.usage.prompt_tokens * 0.06 + response.usage.completion_tokens * 0.12) / 1000
elif 'gpt-3.5-turbo' in response.model:
cost = response.usage.total_tokens * 0.002 / 1000
elif 'davinci' in response.model:
cost = response.usage.total_tokens * 0.02 / 1000
elif 'curie' in response.model:
cost = response.usage.total_tokens * 0.002 / 1000
elif 'babbage' in response.model:
cost = response.usage.total_tokens * 0.0005 / 1000
elif 'ada' in response.model:
cost = response.usage.total_tokens * 0.0004 / 1000
else:
cost = 0
return cost
Elastic 来解救
一旦我们捕获了所有这些数据,就可以在 Elastic 中体验一些乐趣了。在 Discover 中,我们可以看到我们使用 OpenTelemetry 库发送的所有数据点
有了这些标签,就可以很容易地构建一个仪表板。看看我之前构建的这个 (它也已签入我的 GitHub 存储库)
我们还可以看到事务、OpenAI 服务的延迟以及与我们的 ChatGPT 服务调用相关的所有 span。
在事务视图中,我们还可以看到特定的 OpenAI 调用花费了多长时间
此处对 OpenAI 的某些请求花费了 3 秒以上。ChatGPT 的速度可能非常慢,因此对于我们来说,了解它的速度有多慢以及用户是否感到沮丧非常重要。
总结
我们研究了使用 OpenTelemetry 和 Elastic 监控 ChatGPT。ChatGPT 是一种世界性的现象,它无疑会不断增长和发展,很快每个人都会使用它。由于获取响应可能很慢,因此对于人们来说,能够了解使用此服务的任何代码的性能至关重要。
还有一个成本问题,因为了解这项服务是否正在侵蚀您的利润,以及您所要求的服务是否对您的业务有利可图至关重要。在当前的经济环境下,我们必须关注盈利能力。
请查看此解决方案的 代码。并且请随意使用“monitor”库来检测您自己的 OpenAI 代码。
有兴趣了解更多关于 Elastic Observability 的信息吗?请查看以下资源
并注册参加我们与 AWS 和 Forrester 合作的 Elastic Observability 趋势网络研讨会,不容错过!
在本篇博文中,我们可能使用了第三方生成式 AI 工具,这些工具由其各自的所有者拥有和运营。Elastic 对第三方工具没有任何控制权,并且我们对其内容、操作或使用,以及因您使用此类工具而可能造成的任何损失或损害概不负责。在使用包含个人、敏感或机密信息的 AI 工具时,请务必谨慎。您提交的任何数据都可能用于 AI 训练或其他目的。我们无法保证您提供的信息将被安全或保密。在使用任何生成式 AI 工具之前,您应熟悉其隐私实践和使用条款。
Elastic、Elasticsearch 和相关标记是 Elasticsearch N.V. 在美国和其他国家/地区的商标、徽标或注册商标。所有其他公司和产品名称均为其各自所有者的商标、徽标或注册商标。