Python 应用可观测重磅上线:解决 LLM 应用落地的“最后一公里”问题

作者:彦鸿

背景

随着 LLM(大语言模型)技术的不断成熟和应用场景的不断拓展,越来越多的企业开始将 LLM 技术纳入自己的产品和服务中。LLM 在自然语言处理方面表现出令人印象深刻的能力。然而,其内部机制仍然不明确,这种缺乏透明度的做法给下游应用带来了不必要的风险,这也导致了 LLM 应用落地难等问题。因此,理解和解释这些模型对于阐明其行为、局限性和社会影响至关重要。LLM 可观测性能够为模型可解释性提供必要的数据支撑,对于研究人员和开发人员来说,LLM 应用可观测,可以识别意外的偏见、风险和性能改进。

作为 AI 时代的编程语言,Python 在近年来得到了广泛的应用。目前热门的 LLM 项目,如 Langchain、Llama-index、Dify、PromptFlow、OpenAI、Dashscope 等均使用 Python 语言进行开发。为增强对 Python 应用,特别是 Python LLM 应用的可观测性,阿里云推出了 Python 探针,旨在解决 LLM 应用落地难、难落地等问题。助力企业落地 LLM。

本文将从阿里云 Python 探针的接入步骤、产品能力、兼容性等方面展开介绍。并提供一个简单的 LLM 应用例子,方便测试。

应用示例

为方便大家理解和感受 Python 探针的功能,本文构建了一个 LLM 应用的示例:

某公司升级了其产品,新增了智能问答功能。其基本架构图如下:

基本业务流程为用户向 server 端发起一个问答请求,server 去调用 chatbot 获取回复结果,chatbot 收到请求后进行 RAG 后回复。

为观测此 LLM 应用,该公司接入了阿里云 Python 探针。下文将介绍如何接入阿里云 Python 探针。

Python 应用接入应用监控

以下为在 ACK 环境下 Python 探针的接入方式,其他接入方式见:https://help.aliyun.com/zh/arms/application-monitoring/user-guide/start-monitoring-python-applications/

前提条件

  • 创建 Kubernetes 集群。您可按需选择创建 ACK 专有集群、创建 ACK 托管集群或创建 ACK Serverless 集群。
  • 创建命名空间,具体操作,请参见管理命名空间与配额。本文示例中的命名空间名称为 arms-demo。
  • 检查您的 Python 版本和框架版本。具体要求,请参见 Python 探针兼容性要求。

步骤一:安装 ARMS 应用监控组件

  1. 登录容器服务管理控制台 [ 1]

  2. 在左侧导航栏单击集群,然后在集群列表页面单击目标集群名称。

  3. 在左侧导航栏选择运维管理 > 组件管理,然后在右上角通过关键字搜索 ack-onepilot。 (重要:请确保 ack-onepilot 的版本在 3.2.4 及以上。)

  4. 在 ack-onepilot 卡片上单击安装。 (说明:ack-onepilot 组件默认支持 1000 个 pod 规模,集群 pod 每超过 1000 个,ack-onepilot 资源对应的 CPU 请增加 0.5 核、内存请增加 512M。)

  5. 在弹出的页面中可以配置相关的参数,建议使用默认值,单击确定。 (说明:安装完成后,您可以在组件管理页面升级、配置或卸载 ack-onepilot 组件。)

步骤二:修改 Dockerfile

  1. 首先从 pypi 仓库下载探针安装器
pip3 install aliyun-bootstrap
  1. 使用 aliyun-bootstrap 安装探针
aliyun-bootstrap -a install
  1. 使用阿里云 python 探针启动
aliyun-instrument python app.py
  1. 构建镜像,具体的 Dockerfile 示例如下:

Dockerfile 示例:

更改前的 Dockerfile:

# 使用Python 3.10基础镜像
FROM docker.m.daocloud.io/python:3.10# 设置工作目录
WORKDIR /app# 复制requirements.txt文件到工作目录
COPY requirements.txt .# 使用pip安装依赖
RUN pip install --no-cache-dir -r requirements.txtCOPY ./app.py /app/app.py
# 暴露容器的8000端口
EXPOSE 8000
CMD ["python","app.py"]

更改后的 Dockerfile:

# 使用官方的Python 3.10基础镜像
FROM docker.m.daocloud.io/python:3.10# 设置工作目录
WORKDIR /app# 复制requirements.txt文件到工作目录
COPY requirements.txt .# 使用pip安装依赖
RUN pip install --no-cache-dir -r requirements.txt
#########################安装aliyun python 探针###############################
RUN pip3 install  aliyun-bootstrap  && aliyun-bootstrap -a install
##########################################################COPY ./app.py /app/app.py# 暴露容器的8000端口
EXPOSE 8000
#########################################################
CMD ["aliyun-instrument","python","app.py"]

注意事项(必看)

  1. 有使用 unicorn 启动的应用推荐使用以下命令做替换:

例如:

unicorn -w 4 -b 0.0.0.0:8000 app:app

更改为:

gunicorn -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 app:app
  1. 有使用 gevent 协程的需要配置参数

程序中有使用

from gevent import monkey

monkey.patch_all()

需要设置环境变量 GEVENT_ENABLE=true

GEVENT_ENABLE=true

步骤三:授予 ARMS 资源的访问权限

  • 如果需监控 ASK(容器服务 Serverless 版)或对接了 ECI 的集群应用,请在云资源访问授权 [ 2] 页面完成授权,然后重启 ack-onepilot 组件下的所有 Pod。
  • 如果需监控 ACK 集群应用,但 ACK 集群中不存在 ARMS Addon Token,请执行以下操作手动为集群授予 ARMS 资源的访问权限。如果已经存在 ARMS Addon Token,请跳转至步骤四。

查看集群是否存在 ARMS Addon Token:

a. 登录容器服务管理控制台,在集群列表页面,单击目标集群名称进入集群详情页。
b. 在左侧导航栏选择配置管理 > 保密字典,然后在顶部选择命名空间为kube-system,查看addon.arms.token是否存在。

说明:集群存在 ARMS Addon Token 时,ARMS 会进行免密授权。Kubernetes 托管版集群默认存在 ARMS Addon Token,但对于部分早期创建的 Kubernetes 托管版集群,可能会存在没有 ARMS Addon Token 的情况,因此,对于 Kubernetes 托管版集群,建议首先检查 ARMS Addon Token 是否存在。若不存在,需进行手动授权。

  1. 登录容器服务管理控制台。

  2. 在左侧导航栏选择集群,然后单击目标集群名称。

  3. 在目标集群的集群信息页面单击集群资源页签,然后单击 Worker RAM 角色右侧的链接。

  4. 在角色页面的权限管理页签上,单击新增授权。

  5. 选择权限为 AliyunARMSFullAccess,然后单击确定。 (如果需要监控专有版集群和注册集群应用,请确认对应的阿里云账号已包含 AliyunARMSFullAccess 和 AliyunSTSAssumeRoleAccess 权限。添加权限的操作,请参见为 RAM 用户授权 [ 3]

安装 ack-onepilot 组件后,还需要在 ack-onepilot 中填写有 ARMS 权限的阿里云账号 AK/SK。

  1. 在左侧导航栏选择应用 > Helm 页面,单击 ack-onepilot 组件右侧的更新。

  2. 将 accessKey 和 accessKeySecret 替换为当前账号的 AccessKey,然后单击确定。 (说明:获取 AccessKey 的操作,请参见创建 AccessKey [ 4] 。)

  3. 重启应用 Deployment。

步骤四:为 Python 应用开启 ARMS 应用监控

  1. 在容器服务管理控制台左侧导航栏单击集群,在集群列表页面上的目标集群右侧操作列单击应用管理。

  2. 在无状态页面的目标应用右侧选择更多 > 查看 YAML。 (如需创建一个新应用,单击右上角的使用 YAML 创建资源。)

  3. 在 YAML 文件中将以下 labels 添加到 spec.template.metadata 层级下。

labels:aliyun.com/app-language: python # Python应用必填,标明此应用是Python应用。armsPilotAutoEnable: 'on'armsPilotCreateAppName: "<your-deployment-name>"    #应用在ARMS中的展示名称。

创建一个无状态(Deployment)应用并开启 ARMS 应用监控的完整 YAML 示例模板如下:

apiVersion: apps/v1
kind: Deployment
metadata:labels:app: arms-python-clientname: arms-python-clientnamespace: arms-demo
spec:progressDeadlineSeconds: 600replicas: 1revisionHistoryLimit: 10selector:matchLabels:app: arms-python-clientstrategy:rollingUpdate:maxSurge: 25%maxUnavailable: 25%type: RollingUpdatetemplate:metadata:labels:app: arms-python-clientaliyun.com/app-language: python # Python应用必填,标明此应用是Python应用。armsPilotAutoEnable: 'on'armsPilotCreateAppName: "arms-python-client"    #应用在ARMS中的展示名称。spec:containers:- image: registry.cn-hangzhou.aliyuncs.com/arms-default/python-agent:arms-python-clientimagePullPolicy: Alwaysname: clientresources:requests:cpu: 250mmemory: 300MiterminationMessagePath: /dev/termination-logterminationMessagePolicy: FilednsPolicy: ClusterFirstrestartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30---apiVersion: apps/v1
kind: Deployment
metadata:labels:app: arms-python-servername: arms-python-servernamespace: arms-demo
spec:progressDeadlineSeconds: 600replicas: 1revisionHistoryLimit: 10selector:matchLabels:app: arms-python-serverstrategy:rollingUpdate:maxSurge: 25%maxUnavailable: 25%type: RollingUpdatetemplate:metadata:labels:app: arms-python-serveraliyun.com/app-language: python # Python应用必填,标明此应用是Python应用。armsPilotAutoEnable: 'on'armsPilotCreateAppName: "arms-python-server"    #应用在ARMS中的展示名称。spec:containers:- env:- name: CLIENT_URLvalue: 'http://arms-python-client-svc:8000'- image: registry.cn-hangzhou.aliyuncs.com/arms-default/python-agent:arms-python-serverimagePullPolicy: Alwaysname: serverresources:requests:cpu: 250mmemory: 300MiterminationMessagePath: /dev/termination-logterminationMessagePolicy: FilednsPolicy: ClusterFirstrestartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30---apiVersion: v1
kind: Service
metadata:labels:app: arms-python-servername: arms-python-server-svcnamespace: arms-demo
spec:internalTrafficPolicy: ClusteripFamilies:- IPv4ipFamilyPolicy: SingleStackports:- name: httpport: 8000protocol: TCPtargetPort: 8000selector:app: arms-python-serversessionAffinity: Nonetype: ClusterIPapiVersion: v1
kind: Service
metadata:name: arms-python-client-svcnamespace: arms-demouid: 91f94804-594e-495b-9f57-9def1fdc7c1d
spec:internalTrafficPolicy: ClusteripFamilies:- IPv4ipFamilyPolicy: SingleStackports:- name: httpport: 8000protocol: TCPtargetPort: 8000selector:app: arms-python-clientsessionAffinity: Nonetype: ClusterIP

执行结果

待容器完成自动重新部署后,等待 1~2 分钟,在 ARMS 控制台的应用监控 > 应用列表页面单击应用名称,查看应用的监控指标。更多信息,请参见查看监控详情(新版)。

产品能力

应用接入成功后,就可以通过:https://arms.console.aliyun.com/#/tracing/list/cn-hangzhou 来查看 Python 应用的信息了。以下是一些内容的展示:

调用链分析

微服务场景

调用链分析功能可以通过自由组合筛选条件与聚合维度进行实时分析,并支持通过错/慢 Trace 分析功能,定位系统或应用产生错、慢调用的原因。

调用链详情:

大模型场景

针对大模型场景,您可以查看 LLM 领域的新版 TraceView,更直观地分析不同操作类型的输入输出、Token 消耗等信息。

首先切换为大模型视图:

具体的大模型调用信息:

监控指标

应用概览

应用拓扑

配置告警

通过配置告警,您可以制定针对特定应用的告警规则。当告警规则被触发时,系统会以您指定的通知方式向告警联系人或钉群发送告警信息,以提醒您采取必要的解决措施。具体操作,请参见应用监控告警规则 [ 5]

兼容性

Python 版本>=3.8

附件

arms-python-server:

import uvicorn
from fastapi import FastAPI, HTTPException
from logging import getLogger
from concurrent import futures
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
_logger = getLogger(__name__)
import requests
import osdef call_requests():url = 'https://www.aliyun.com'  # 替换为你的实际地址call_url = os.environ.get("CALL_URL")if call_url is None or call_url == "":call_url = url# try:response = requests.get(call_url)response.raise_for_status()  # 如果请求返回了错误码则抛出异常print(f"response code: {response.status_code} - {response.text}")app = FastAPI()def call_client():_logger.warning("calling client")url = 'https://www.aliyun.com'  # 替换为你的实际地址call_url = os.environ.get("CLIENT_URL")if call_url is None or call_url == "":call_url = urlresponse = requests.get(call_url)# print(f"response code: {response.status_code} - {response.text}")return response.text@app.get("/")
async def call():with tracer.start_as_current_span("parent") as rootSpan:rootSpan.set_attribute("parent.value", "parent")with futures.ThreadPoolExecutor(max_workers=2) as executor:with tracer.start_as_current_span("ThreadPoolExecutorTest") as span:span.set_attribute("future.value", "ThreadPoolExecutorTest")future = executor.submit(call_client)future.result()
# call_client()return {"data": f"call"}if __name__ == "__main__":uvicorn.run(app, host="0.0.0.0", port=8000)

arms-python-client:

from fastapi import FastAPI
from langchain.llms.fake import FakeListLLM
import uvicorn
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplateapp = FastAPI()
llm = FakeListLLM(responses=["I'll callback later.", "You 'console' them!"])template = """Question: {question}Answer: Let's think step by step."""prompt = PromptTemplate(template=template, input_variables=["question"])llm_chain = LLMChain(prompt=prompt, llm=llm)question = "What NFL team won the Super Bowl in the year Justin Beiber was born?"@app.get("/")
def call_langchain():res = llm_chain.run(question)return {"data": res}if __name__ == "__main__":uvicorn.run(app, host="0.0.0.0", port=8000)

相关链接:

[1] 容器服务管理控制台

https://account.aliyun.com/login/login.htm?oauth_callback=https%3A%2F%2Fcs.console.aliyun.com%2F

[2] 云资源访问授权

https://account.aliyun.com/login/login.htm?oauth_callback=https%3A%2F%2Fram.console.aliyun.com%2Frole%2Fauthorization%3Frequest%3D%257B%2522Services%2522%253A%255B%257B%2522Service%2522%253A%2522ECS%2522%252C%2522Roles%2522%253A%255B%257B%2522RoleName%2522%253A%2522AliyunMSEForECIRole%2522%252C%2522TemplateId%2522%253A%2522AliyunMSEForECIRole%2522%257D%255D%257D%255D%252C%2522ReturnUrl%2522%253A%2522https%253A%252F%252Farms.console.aliyun.com%2522%257D&clearRedirectCookie=1&lang=zh

[3] RAM 用户授权

https://help.aliyun.com/zh/ram/user-guide/grant-permissions-to-the-ram-user

[4] 创建 AccessKeyhttps://help.aliyun.com/zh/ram/user-guide/create-an-accesskey-pair

[5] 应用监控告警规则

https://help.aliyun.com/zh/arms/application-monitoring/user-guide/create-and-manage-alert-rules-in-application-monitoring-new/

参考链接:

https://help.aliyun.com/zh/arms/application-monitoring/user-guide/start-monitoring-python-applications/

https://help.aliyun.com/zh/arms/application-monitoring/developer-reference/python-probe-compatibility-requirements

点击此处立即开通 ARMS - 应用监控,享受每月 50GB 免费额度!加入钉钉群(群号:35568145)获得在线技术支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/58002.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

城市景色视频素材下载好去处

在制作短视频、Vlog 或商业宣传片时&#xff0c;城市景色视频素材能为作品增添现代感与活力。繁华都市、流光溢彩的夜景、清晨街道等都是展现城市魅力的好素材。那么城市景色视频素材去哪里下载呢&#xff1f; 蛙学网 是专为短视频创作者打造的素材平台&#xff0c;城市景色素材…

[bug] vllm 0.6.1 RuntimeError: operator torchvision::nms does not exist

[bug] vllm 0.6.1 RuntimeError: operator torchvision::nms does not exist 环境 python 3.10 torch 2.4.0cu118 torchvision 0.19.0cu118 vllm 0.6.1.post2cu118问题详情 if torch._C._d…

嵌入式软开——八股文——学习引导和资料网址

1、找工作期间整理的相关八股资料&#xff0c;可以帮助初学者按此流程快速学习入门&#xff0c;帮助有基础的同学快速复习、查缺补漏&#xff0c;帮助找工作面试的同学&#xff0c;快速复习知识点。 2、前13个文件夹为单独模块的相关学习内容&#xff0c;里面涵盖相关模块的主…

零基础Java第十一期:类和对象(二)

目录 一、对象的构造及初始化 1.1. 就地初始化 1.2. 默认初始化 1.3. 构造方法 二、封装 2.1. 封装的概念 2.2. 访问限定符 2.3. 封装扩展之包 三、static成员 3.1. 再谈学生类 3.2. static修饰成员变量 一、对象的构造及初始化 1.1. 就地初始化 在声明成员变…

耦合回路网络

目录 去耦 阻抗 初级回路对次级回路的影响 次级回路对初级回路的影响 对比 物理意义 讨论: 谐振时 ​编辑 谐振 耦合回路谐振分类 部分谐振 复谐振 全谐振 要研究耦合回路 , 就要先进行去耦的工作 去耦 对于去耦的方法 , 总共列出两个方程 , 初级回路与次级回路的方程求解…

傻瓜式AI头像生成

01、先看看看效果 02、第一步 输入关键词&#xff1a;Design by Disney Pixar Studio, by craig mccracken, maintaining consistency in the actions, expressions, clothing, shape, and appearance of the photos, three-quarter side looking at camera, a cute 20-year-ol…

第11次CCF CSP认证真题解

1、打酱油 题目链接&#xff1a;https://sim.csp.thusaac.com/contest/11/problem/0 本题只需推导出所有输出样例都满足的规律式并输出即可。 100代码&#xff1a; #include <iostream> using namespace std; int main(int argc, char *argv[]) {int n;cin >> …

IntelliJ IDEA 设置数据库连接全局共享

前言 在日常的软件开发工作中&#xff0c;我们经常会遇到需要在多个项目之间共享同一个数据库连接的情况。默认情况下&#xff0c;IntelliJ IDEA 中的数据库连接配置是针对每个项目单独存储的。这意味着如果你在一个项目中配置了一个数据库连接&#xff0c;那么在另一个项目中…

Axure简单进度条制作,原型文件可下载

1.先看效果 2.需要用到的主要元件 a动态面板遮挡进度条左侧部分 b进度条底色背景 c百分比数字 3.将进度条、背景、百分比数字设置为隐藏 4.为按钮【选择文件】添加事件&#xff0c;并显示相应的原件 显示进度条process向右侧滑动 5.设置百分比数字及显示时每25毫秒加1 如…

nuxt数据库之增删改查,父组件子组件传值

nuxt学到数据库这里&#xff0c;就涉及到响应数据&#xff0c;父组件向子组件传值&#xff0c;子组件向父组件传值&#xff0c;最终还是需要掌握vue3的组件知识了。学习真的是一个长期的过程&#xff0c;不管学习了什么知识&#xff0c;有多少&#xff0c;都应该及时的记录下来…

Python 判断键是否存在字典中(新手入门、实战案例)

在早期的Python2版本中&#xff0c;可以使用 dict.has_key()方法来判断一个键是否存在于字典中。 在Python3中&#xff0c;dict.has_key()方法被废弃了&#xff0c;不能再被使用。如果在Python3中尝试使用dict.has_key()方法会导致 AttributeError异常。 那在Python3中要如何判…

k8s-service详解

Service介绍 在kubernetes中&#xff0c;pod是应用程序的载体&#xff0c;我们可以通过pod的ip来访问应用程序&#xff0c;但是pod的ip地址不是固定的&#xff0c;这也就意味着不方便直接采用pod的ip对服务进行访问。 为了解决这个问题&#xff0c;kubernetes提供了Service资源…

关于Docker的docker engine stopped问题解决

问题图: 主要检查这两块 启用或关闭Windows功能如下图&#xff08;将没开启的开启特别是Hyper-V&#xff0c;Linux&#xff0c;虚拟机等&#xff09;&#xff1a; 然后打开任务管理器搜索Docker service将关闭状态打开 运行管理员CMD执行如下命令 重启&#xff01;&#xff01…

Uni-App-01

HBuilder安装卸载 安装 官网地址&#xff1a;https://www.dcloud.io/hbuilderx.html 下载HBuilder最新版 解压到安装目录&#xff0c;路径中不要有中文和空格 在桌面上增加快捷方式 卸载 执行reset.bat 删除HBuilder文件夹&#xff08;如果提示文件被占用&#xff0…

使用语音模块的开发智能家居产品(使用雷龙LSYT201B 语音模块)

在这篇博客中&#xff0c;我们将探讨如何使用 LSYT201B 语音模块 进行智能设备的语音交互开发。通过这个模块&#xff0c;我们可以实现智能设备的语音识别和控制功能&#xff0c;为用户带来更为便捷和现代的交互体验。 1. 语音模块介绍 LSYT201B 是一个基于“芯片算法”的语音…

Centos7.9安装MySQL(二进制)

安装包 https://downloads.mysql.com/archives/community/ mysql-8.0.39-linux-glibc2.17-x86_64.tar.xz 1.卸载MariaDB 查看 rpm -qa|grep mariadb卸载 可能名称不一样&#xff0c;记得替换 rpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_64rpm -qa|grep mariadb 执行…

C++游戏开发中的多线程处理是否真的能够显著提高游戏性能?如果多个线程同时访问同一资源,会发生什么?如何避免数据竞争?|多线程|游戏开发|性能优化

目录 1. 多线程处理的基本概念 1.1 多线程的定义 1.2 线程的创建与管理 2. 多线程在游戏开发中的应用 2.1 渲染与物理计算 3. 多线程处理的性能提升 3.1 性能评估 3.2 任务分配策略 4. 多线程中的数据竞争 4.1 数据竞争的定义 4.2 多线程访问同一资源的后果 4.3 避…

数字后端零基础入门系列 | Innovus零基础LAB学习Day5

###Module 12 RC参数提取和时序分析 数字后端零基础入门系列 | Innovus零基础LAB学习Day4 数字后端零基础入门系列 | Innovus零基础LAB学习Day3 数字后端零基础入门系列 | Innovus零基础LAB学习Day2 数字后端零基础入门系列 | Innovus零基础LAB学习Day1 ###LAB12-1 这个章节…

六自由度机械臂模型预测控制MPC+倒立摆+二自由度机械臂

接下来三个例子教你入门mpc&#xff0c;为了体现视频的高质量&#xff0c;在倒立摆和二自由度模型预测控制方面&#xff0c;我会给出一种基于状态变量微分的实时线性化策略&#xff0c;经过这样处理的mpc实际可以看作是nmpc。 1.一阶倒立摆MPC 1.1倒立摆状态方程 1.2倒立摆状…

rabbitmq 使用注意事项

1&#xff0c;注意开启的端口号&#xff0c;一共四个端口号&#xff0c;1883是mqtt连接的端口号&#xff0c;如果没开&#xff0c;是连接不上的需要手动起mqtt插件。 //开始mqtt插件服务 rabbitmq-plugins enable rabbitmq_mqtt 2&#xff0c;15672端口是http网页登录的管理后…