使用streamlit实现vLLM多实例信息统一监控

本文代码和配置文件实现了一个基于 Streamlit 和 FastAPI 的前后端分离的应用程序,用于管理和展示 VLLM(Very Large Language Model)实例的信息。以下是代码和配置文件的总结摘要:

概要

功能概述

  1. 前后端启动方式

    • 使用 Streamlit 启动前端界面,可通过默认端口或指定端口和 IP 启动。
    • 使用 Uvicorn 启动 FastAPI 后端服务,用于提供模型数据的 API 接口。
  2. 前端功能(Streamlit)

    • 支持可选的登录认证功能,通过 YAML 配置文件控制是否启用。
    • 展示 VLLM 模型的概览信息,包括模型名称、路径、IP 地址、端口、任务 ID、启动时间等。
    • 从后端 API 获取模型数据,并动态展示模型的详细信息。
    • 提供刷新按钮,用于重新从后端获取数据并更新前端显示。
  3. 后端功能(FastAPI)

    • 提供 /models/models/{model_name} 两个 API 接口。
    • /models 接口返回所有 VLLM 模型的列表信息。
    • /models/{model_name} 接口根据模型名称返回特定模型的详细信息。
    • 使用 ps 命令解析系统进程信息,提取 VLLM 模型的运行参数和启动时间。
  4. 配置文件

    • counter.yaml:用于配置后端 API 的端口号和是否启用前端登录认证。
    • .streamlit/secrets.toml:存储前端登录认证的用户名和密码。
  5. 模型信息展示

    • 模型信息通过 st.expander 展开式组件展示,包含模型的基本信息和参数。
    • 计算模型的运行时间(uptime),并以友好的格式显示。

技术栈

  • 前端:Streamlit,用于快速搭建交互式 Web 界面。
  • 后端:FastAPI,用于构建高效的 API 服务。
  • 数据解析:通过 ps 命令获取系统进程信息,并解析出 VLLM 模型的运行参数。
  • 配置管理:使用 YAML 和 TOML 文件分别管理后端配置和前端认证信息。

使用场景

该应用适用于管理和监控运行在服务器上的 VLLM 模型实例,通过前端界面直观地展示模型的运行状态和参数配置,方便用户进行管理和调试。

代码展示

应用前后端启动方式

#默认启动
streamlit run app.py
#Local URL: http://localhost:8501#指定端口 ip
streamlit run app.py --server.address 0.0.0.0 --server.port 8501# unicorn启动后端fastapi
uvicorn api:app --reload --port 8880

Streamlit 代码(前端页面)

import streamlit as stimport requestsfrom datetime import datetime# 设置页面配置st.set_page_config(page_title="VLLM 概览",page_icon="📊")# 登录认证try:import yamlwith open('counter.yaml') as f:config = yaml.safe_load(f)need_auth = config.get('web.auth', False)except Exception as e:need_auth = Falseif need_auth:if 'authenticated' not in st.session_state:st.session_state['authenticated'] = Falseif not st.session_state['authenticated']:st.header("请登录")username = st.text_input("用户名")password = st.text_input("密码", type="password")if st.button("登录"):if username == st.secrets["auth"]["vstu"] and password == st.secrets["auth"]["vstp"]:st.session_state['authenticated'] = Truest.rerun()else:st.error("用户名或密码错误")st.stop()# 页面标题st.header("📊 VLLM 模型概览")# 模拟API获取数据函数def fetch_vllm_models():# 从配置文件读取端口号try:import yamlwith open('counter.yaml') as f:config = yaml.safe_load(f)port = config.get('vllm.api.port', 8880)except Exception as e:port = 8880# 调用本地API获取数据response = requests.get(f"http://localhost:{port}/models")if response.status_code == 200:return response.json()return []# 获取数据models = fetch_vllm_models()# 计算运行时间def calculate_uptime(start_time_str):start_time = datetime.fromisoformat(start_time_str)uptime = datetime.now() - start_timereturn str(uptime).split('.')[0]# 展示模型信息for model in models:uptime = calculate_uptime(model['start_time'])with st.expander(f"模型: {model['sname']} ({model['name']})      [⏱️ {uptime}]"):col1, col2 = st.columns(2)with col1:st.write(f"**路径**: {model['path']}")st.write(f"**地址**: {model['ip']}")st.write(f"**端口**: {model['port']}")st.write(f"**任务ID**: {model['pid']}")st.write(f"**启动时间**: {model['start_time']}")with col2:st.write("**参数**:")for param, value in model['params'].items():st.write(f"- {param}: {value}")# 刷新按钮if st.button("刷新数据"):st.rerun()

API 代码

from fastapi import FastAPIfrom datetime import datetimefrom pydantic import BaseModelimport osapp = FastAPI()class ModelInfo(BaseModel):name: strsname: strpath: strip: strport: intstart_time: strparams: dict# 模拟数据models = [{"name": "model1","sname": "model1","path": "/path/to/model1","ip": "192.168.1.100","port": 8000,"start_time": "2023-01-01T10:00:00","params": {"temperature": 0.7, "max_tokens": 100}},{"name": "model2","sname": "model2","path": "/path/to/model2","ip": "192.168.1.101","port": 8001,"start_time": "2023-01-02T11:00:00","params": {"temperature": 0.8, "max_tokens": 200}}]def parse_ps_time(ps_time_str):"""将ps命令返回的时间字符串转换为ISO格式"""return datetime.strptime(ps_time_str, "%a %b %d %H:%M:%S %Y").isoformat()def parse_vllm_ps_output():"""从ps命令输出解析vllm模型信息"""try:# 使用os.popen直接执行ps命令process = os.popen('ps aux | grep "vllm serve" | grep -v grep')output = process.read()process.close()if not output:print("No vllm processes found")return []models = []for line in output.splitlines():if "vllm serve" not in line:continue# 提取PIDpid = int(line.split()[1])# 提取完整命令cmd_start = line.find("vllm serve")cmd = line[cmd_start:]# 提取模型路径model_path = cmd.split("vllm serve ")[1].split()[0]# 提取参数params = {}ip = "localhost"  # 默认IP地址port = 8000     # 默认端口sname = model_path.split('/')[-1]parts = cmd.split()for i, part in enumerate(parts):if part == "--host":ip = parts[i+1]elif part == "--port":port = int(parts[i+1])elif part == "--task":params["task"] = parts[i+1]elif part == "--tensor-parallel-size":params["tensor_parallel_size"] = int(parts[i+1])elif part == "--pipeline-parallel-size":params["pipeline_parallel_size"] = int(parts[i+1])elif part == "--trust-remote-code":params["trust_remote_code"] = Trueelif part == "--api-key":params["api_key"] = Trueelif part == "--served-model-name":sname = parts[i+1]# 获取进程启动时间time_process = os.popen(f'ps -p {pid} -o lstart=')start_time_str = time_process.read().strip()time_process.close()models.append({"name": model_path.split('/')[-1],"sname": sname,"path": model_path,"pid": pid,"ip": ip,"port": port,"start_time": parse_ps_time(start_time_str) if start_time_str else datetime.now().isoformat(),"params": params})return modelsexcept Exception as e:print(f"Error parsing ps output: {e}")return []@app.get("/models")async def get_models():return parse_vllm_ps_output()@app.get("/models/{model_name}")async def get_model(model_name: str):for model in models:if model["name"] == model_name:return modelreturn {"error": "Model not found"}

配置文件的内容示例

# counter.yaml
vllm.api.port: 8880
web.auth: false

密码文件的内容示例

# .streamlit\secrets.toml
[auth]
vstu = "admin"
vstp = "your_password"

效果展示

展示所有的运行中的模型信息,包括当前模型已运行的时间。

下拉菜单可以展示模型的详细信息,如参数、地址、端口等信息。

总结

这段代码实现了一个基于 Streamlit 和 FastAPI 的应用,用于管理和展示 VLLM 模型实例的信息。前端通过 Streamlit 提供交互式界面,支持登录认证和模型信息的动态展示;后端使用 FastAPI 提供 API 接口,从系统进程解析模型数据。配置文件用于设置端口和认证信息。整体功能包括模型概览、运行时间计算和数据刷新,适合用于监控和管理 VLLM 模型实例。

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

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

相关文章

搭建一个WordPress网站需要多少成本

WordPress 最初可能只是一个简单的博客平台。但近年来,它不仅成为了最好的博客平台,还成为了一个全面的内容管理系统。白宫、jQuery、NGINX、《纽约时报》等企业都把 WordPress 作为自己的网上家园。 不过,它们只是其中的佼佼者。根据 Built…

飞帆控件 post or get it when it has get

我在这里分享两个链接: post_get_it 设计 - 飞帆 有人看出来这个控件是干什么用吗? 控件的配置:

AI智能体 | 使用Coze一键制作“假如书籍会说话”视频,18个作品狂吸17.6万粉,读书博主新标杆!(附保姆级教程)

目录 一、整体工作流设计 二、制作工作流 2.1 开始节点 2.2 大模型_生成对话文案 2.3 代码_字幕切割 2.4 画板_对话背景 2.5 循环_对话语音01 2.5.1 选择器_2 2.5.2 语音合成02 2.5.3 语音合成03 2.5.4 变量聚合_1 2.5.5 视频合成01 2.6 循环_3 2.6.1 选择器_3 …

mysql中4种扫描方式和聚簇索引非聚簇索引【爽文一篇】

目录 一 mysql的聚簇索引&非聚簇索引 1.1 数据表 1.2 聚簇索引 1.3 非聚簇索引 1.4 覆盖索引 二 mysql的4种扫描查询 2.1 全表扫描 2.2 索引扫描 2.3 覆盖索引扫描 2.4 回表扫描 2.5 总结 三 mysql的回表查询详解 3.1 回表查询 一 mysql的聚簇索引&非聚簇…

泛微对接金蝶云星空实战案例技术分享

前言 在企业信息化建设中,OA系统与ERP系统对接往往是一个复杂而关键的环节。OA系统通常具有高度的自定义性,其基础资料和单据可能与ERP系统存在字段不一致等问题。同时,OA系统涉及审批流程及流程发起方定义,增加了对接的复杂性。…

一种资源有限单片机处理cJSON数据的方法

一般单片机处理cJSON格式的数据都直接使用cJSON库,但对于Ram较小的单片机,由于资源有限,这并不合适,但我们可以根据cJSON数据的特定格式,使用土方法,直接对字符进行查找裁剪即可 //截取字符串str中字符a与…

关于软件测试开发的一些有趣的知识

文章目录 一、什么是测试?二、为什么要软件测试软件测试三、测试的岗位有哪些四 、软件测试和开发的区别五、走测试岗位为什么还要学开发。4、优秀的测试人员具备的素质我为什么走测试岗位 一、什么是测试? 其实这个问题说简单也不简单,说难…

【C++ 基础数论】质数判断

质数判断 质数:对于所有大于 1 的自然数而言,如果该数除 1 和自身以外没有其它因数 / 约数,则该数被称为为质数,质数也叫素数。 如何判定一个数是否为质数呢? 一个简单的方法是 试除法 : 对于一个数 n&…

6to4、6over4的类比解释

本文由deepseek生成,特此声明 1. 6to4:自动的“快递中转站” 类比场景: 假设你住在一个偏远的小镇(IPv6网络),周围被大海(IPv4互联网)包围,你想给另一个偏远小镇&#…

数字化工厂升级引擎:Modbus TCP转Profinet网关助力打造柔性生产系统

在当今的工业自动化领域,通信协议扮演着至关重要的角色。Modbus TCP和Profinet是两种广泛使用的工业通信协议,它们分别在不同的应用场景中发挥着重要作用。然而,有时我们可能需要将这两种协议进行转换,以实现不同设备之间的无缝通…

计算机网络-MPLS LDP基础实验配置

前面我们学习了LDP的会话建立、标签发布与交换、LDP的工作原理,今天通过一个基础实验来加深记忆。 一、LDP基础实验 实验拓扑: 1、IGP使用OSPF进行通告,使用Lookback接口作为LSR ID,LDP ID自动生成。 2、实验目的:使…

Ocean: Object-aware Anchor-free Tracking

领域:Object tracking It aims to infer the location of an arbitrary target in a video sequence, given only its location in the first frame 问题/现象: Anchor-based Siamese trackers have achieved remarkable advancements in accuracy, yet…

[Java] 方法和数组

目录 1. 方法 1.2 什么是方法 1.2 方法的定义 1.3 方法的调用 1.4 方法的重载 1.5 递归 2. 一维数组 2.1 什么是数组 2.2 数组的创建 2.3 数组的初始化 2.4 遍历数组 2.5 引用数据类型 2.6 关于null 2.7 数组转字符串 2.8 数组元素的查找 2.9 数组的排序 2.10…

全局异常处理:如何优雅地统一管理业务异常

在软件开发中,异常处理是保证系统健壮性的重要环节。一个良好的异常处理机制不仅能提高代码的可维护性,还能为使用者提供清晰的错误反馈。本文将介绍如何通过全局异常处理和业务异常统一处理来编写更加优雅的代码。 一、传统异常处理的痛点 1.1 典型问…

PHP 编程:现代 Web 开发的基石与演进

引言 PHP(Hypertext Preprocessor)自1995年诞生以来,已成为全球最流行的服务器端脚本语言之一。尽管近年来Node.js、Python等语言在特定领域崭露头角,但PHP仍占据着超过78%的网站市场份额(W3Techs数据)。本…

MCU程序加密保护(一)闪存读写保护法 加密与解密

MCU(微控制器单元)的加密方法可以从硬件、软件和通信协议三个层面来理解。以下是常见的MCU加密手段,按类型分类说明: 针对目前 STM32 系列微控制器在程序加密保护方面手段单一、保护效果有限的问题,本文介绍并分析了四…

汽车装配又又又升级,ethernetip转profinet进阶跃迁指南

1. 场景描述:汽车装配线中,使用EtherNet/IP协议的机器人与使用PROFINET协议的PLC进行数据交互。 2. 连接设备:EtherNet/IP机器人控制器(如ABB、FANUC)与PROFINET PLC(如西门子S7-1500)。 3. 连…

RFID系统:技术解析与应用全景

一、技术架构与运行逻辑 RFID(Radio Frequency Identification)系统通过无线电波实现非接触式数据交互,其核心由三部分组成: 电子标签(Tag): 无源标签:依赖读写器电磁场供电&…

25、DeepSeek-R1论文笔记

DeepSeek-R1论文笔记 1、研究背景与核心目标2、核心模型与技术路线3、蒸馏技术与小模型优化4、训练过程简介5、COT思维链(Chain of Thought)6、强化学习算法(GRPO)7、冷启动**1. 冷启动的目的****2. 冷启动的实现步骤****3. 冷启动…

开源项目实战学习之YOLO11:12.2 ultralytics-models-sam-decoders.py源码分析

👉 点击关注不迷路 👉 点击关注不迷路 👉 另外,前些天发现了一个巨牛的AI人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。感兴趣的可以点击相关跳转链接。 点击跳转到网站。 ultralytics-models-sam 1.sam-modules-decoders.pyblocks.py: 定义模型中的各…