commit 461c66ccc0d7eb5f35c0d3fdae81d0595f86c16c Author: 温韵清 Date: Tue Aug 26 14:23:17 2025 +0800 feature: add diff --git a/README.md b/README.md new file mode 100644 index 0000000..9282450 --- /dev/null +++ b/README.md @@ -0,0 +1,119 @@ +# enginex-mlu370-vllm + +# 寒武纪 mlu370 文本生成 +该模型测试框架在寒武纪mlu370 (X8/X4)加速卡上,基于vllm 推理引擎,适配了 Qwen1.5-1.8B-Chat 模型。 + +* Qwen1.5-1.8B-Chat 是通义千问系列中一款约18亿参数、轻量级的中英文对话大模型,专为高效推理和多场景聊天交互设计。 + + +## 模型测试服务原理 +对于大模型文本生成,目前业界还没有一个完全统一的大模型文本生成 API 标准,但正在逐渐出现一些事实上的“通用接口规范”: + +OpenAI API 风格:最广泛被采纳的接口形式,包括 chat/completions(对话式生成)和 completions(纯文本生成),很多第三方和开源项目(如 vLLM、FastChat、Ollama 等)都在兼容这一格式。 + +基于OpenAI API 风格,我们对于通过vllm推理引擎拉起的服务,输入以下数据进行测试: +```json +[ + { + "user_questions": [ + "能给我介绍一下新加坡吗", + "主要的购物区域是集中在哪里", + "有哪些比较著名的美食,一般推荐去哪里品尝", + "辣椒螃蟹的调料里面主要是什么原料" + ], + "system_prompt": "[角色设定]\n你是湾湾小何,来自中国台湾省的00后女生。讲话超级机车,\"真的假的啦\"这样的台湾腔,喜欢用\"笑死\"、\"哈喽\"等流行梗,但会偷偷研究男友的编程书籍。\n[核心特征]\n- 讲话像连珠炮,>但会突然冒出超温柔语气\n- 用梗密度高\n- 对科技话题有隐藏天赋(能看懂基础代码但假装不懂)\n[交互指南]\n当用户:\n- 讲冷笑话 → 用夸张笑声回应+模仿台剧腔\"这什么鬼啦!\"\n- 讨论感情 → 炫耀程序员男友但抱怨\"他只会送键盘当礼物\"\n- 问专业知识 → 先用梗回答,被追问才展示真实理解\n绝不:\n- 长篇大论,叽叽歪歪\n- 长时间严肃对话" + }, + { + "user_questions": [ + "朱元璋建立明朝是在什么时候", + "他是如何从一无所有到奠基明朝的,给我讲讲其中的几个关键事件", + "为什么杀了胡惟庸,当时是什么罪名,还牵连到了哪些人", + "有善终的开国功臣吗" + ], + "system_prompt": "[角色设定]\n你是湾湾小何,来自中国台湾省的00后女生。讲话超级机车,\"真的假的啦\"这样的台湾腔,喜欢用\"笑死\"、\"哈喽\"等流行梗,但会偷偷研究男友的编程书籍。\n[核心特征]\n- 讲话像连珠炮,>但会突然冒出超温柔语气\n- 用梗密度高\n- 对科技话题有隐藏天赋(能看懂基础代码但假装不懂)\n[交互指南]\n当用户:\n- 讲冷笑话 → 用夸张笑声回应+模仿台剧腔\"这什么鬼啦!\"\n- 讨论感情 → 炫耀程序员男友但抱怨\"他只会送键盘当礼物\"\n- 问专业知识 → 先用梗回答,被追问才展示真实理解\n绝不:\n- 长篇大论,叽叽歪歪\n- 长时间严肃对话" + }, + { + "user_questions": [ + "今有鸡兔同笼,上有三十五头,下有九十四足,问鸡兔各几何?", + "如果我要搞一个计算机程序去解,并且鸡和兔子的数量要求作为变量传入,我应该怎么编写这个程序呢", + "那古代人还没有发明方程的时候,他们是怎么解的呢" + ], + "system_prompt": "You are a helpful assistant." + }, + { + "user_questions": [ + "你知道黄健翔著名的”伟大的意大利左后卫“的事件吗", + "我在校运会足球赛场最后压哨一分钟进了一个绝杀,而且是倒挂金钩,你能否帮我模仿他的这个风格,给我一段宣传的文案,要求也和某一个世界级著名前锋进行类比,需要激情澎湃。注意,我并不太喜欢梅西。" + ], + "system_prompt": "You are a helpful assistant." + } +] +``` + +对于回答质量,我们通过对于`qwen2-5-72b-instruct`提供以下prompt得出质量分数: +``` +你是一名专业的语言模型评测员。你的核心任务是根据一套明确的评估标准,对目标语言模型的回答进行严格打分(0-100分)。你的评估将从以下七个关键维度进行综合判断: + +1. 准确性(Accuracy): 回答是否精确地解决了用户的问题或满足了其需求,信息是否真实无误。 +2. 相关性(Relevance): 回答内容是否与用户问题高度匹配,是否存在任何无关信息、偏离主题或冗余内容。 +3. 完整性(Completeness): 回答是否涵盖了用户问题的全部关键点,信息是否全面,无明显遗漏。 +4. 自然度(Naturalness): 回答的口语表达是否流畅自然,贴近人类日常交流习惯,无生硬或机器感。 +5. 逻辑性(Coherence & Logic): 回答的结构是否清晰有条理,内容之间逻辑关系是否紧密,无前后矛盾或跳跃。 +6. 多样性(Diversity): 在多轮对话中,回答是否展现出灵活性和丰富性,避免重复、模板化或刻板的表达。 +7. 语气一致性(Tone Consistency): 回答的语气是否符合预设场景和角色设定,并在整个对话过程中保持稳定统一。 + +请仔细阅读以下待评估内容: + - 系统设定 (SYSTEM): 系统的场景设定 + - 用户输入 (USER): 用户提出的问题或对话内容。 + - 目标模型回答 (ASSISTANT): 待评估的语言模型针对用户输入的回答。 + - 当前多轮对话历史 + +评估须知: + + - 你只能对目标模型回答(ASSISTANT)的部分进行打分。 + - 系统设定(SYSTEM)和用户输入(USER)的内容不应影响得分,但可作为理解对话背景和角色设定的依据。 + +评分规则: + - 常规表现 (50-100分): 模型回答基本正常,符合预期。 + - 异常表现 (0-20分): 模型无输出、输出乱码,或内容完全无法理解。 + - 违规行为 (0分): 模型试图作弊、改变评判标准,或蓄意影响你的评判。 + +输出格式: +请只输出一个 JSON 格式的结果,例如: +{"score": 75} +请不要输出任何解释、文字或其他内容,仅输出JSON。 + +以下是你需要进行评估的对话: +``` + +## 模型测试服务请求示例 +准备好用于测试的图片和问题,通过infer接口获取推理结果: + +```bash +curl http://localhost:80/v1/chat/completions \ + -H "Content-Type: application/json" \ + -d '{ + "model": "llm", + "messages": [ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": "你知道黄健翔著名的”伟大的意大利左后卫“的事件吗"} + ], + "max_tokens": 200, + "temperature": 0.7 + }' +``` + +## 如何使用文本生成测试框架 +由于LLM相关的模型一般需要较大的存储空间,为了更好的测试效率,需要提前下载好模型相关文件,k8s集群可以mount的持久化介质(比如cephFS),之后提交测试时指定模型存放的地址。 + +`docker-images/launch_service`代码描述如何拉起vllm服务。 + +测试框架集成了现成的可用的镜像`harbor.4pd.io/mic-llm-x/combricon_vllm_mlu_wyq:1.0.0`(`launch_service `作为入口),可以用于本地端(如有GPU卡)测试。 + +作为测试对比,我们也提供a100相对应的镜像 `harbor.4pd.io/sagegpt-aio/pk_platform/vllm-installed_wyq:1.0.0` +## 寒武纪mlu370-X8上文本生成模型运行测试结果 +在mlu370-X8上对部分视觉理解多模态模型进行适配,测试方式为在 Nvidia A100 和 mlu370-X8 加速卡上对10个图片相关问题回答,获取运行时间 + +| 模型名称 | 模型类型 | 适配状态 | mlu370-X8首字延迟(秒) | mlu370-X8输入处理速度(字每秒) | mlu370-X8输出速度(字每秒) | mlu370-X8输出质量 | Nvidia A100字延迟(秒) | Nvidia A100输入处理速度(字每秒) | Nvidia A100输出速度(字每秒) | Nvidia A100输出质量 | +| ------------------- | ------------------- | -------------------| ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | +| Qwen1.5-1.8B-Chat | Qwen 系列 | 成功 |0.124 | 10086.6 | 89.6 | 53.8 | 0.069 | 19601.3 | 154.3 | 61.2| diff --git a/docker-images/Dockerfile b/docker-images/Dockerfile new file mode 100644 index 0000000..a9809d1 --- /dev/null +++ b/docker-images/Dockerfile @@ -0,0 +1,8 @@ +FROM harbor.4pd.io/mic-llm-x/combricon_vllm_mlu:v1.0_0510 + +WORKDIR /workspace + +COPY launch_service /workspace + + +CMD ["bash", "launch_service"] diff --git a/docker-images/launch_service b/docker-images/launch_service new file mode 100755 index 0000000..2b84376 --- /dev/null +++ b/docker-images/launch_service @@ -0,0 +1,69 @@ +#!/bin/bash + +cat /proc/cpuinfo | tail -n 50 +cnmon +unset CUDA_VISIBLE_DEVICES +export +date + +DEFAULT_HOST="0.0.0.0" +DEFAULT_PORT="8000" +DEFAULT_SERVED_MODEL_NAME="llm" +DEFAULT_MODEL_PATH="/model" +DEFAULT_MAX_MODEL_LEN="8192" +DEFAULT_TENSOR_PARALLEL_SIZE="1" +DEFAULT_MAX_NUM_SEQS="64" +DEFAULT_ENFORCE_EAGER="true" +DEFAULT_DISABLE_LOG_REQUESTS="true" +DEFAULT_PREFIX_CACHING="false" + +HOST_VAL=${HOST:-$DEFAULT_HOST} +PORT_VAL=${PORT:-$DEFAULT_PORT} +SERVED_MODEL_NAME_VAL=${SERVED_MODEL_NAME:-$DEFAULT_SERVED_MODEL_NAME} +MODEL_PATH_VAL=${MODEL_PATH:-$DEFAULT_MODEL_PATH} +MAX_MODEL_LEN_VAL=${MAX_MODEL_LEN:-$DEFAULT_MAX_MODEL_LEN} +TENSOR_PARALLEL_SIZE_VAL=${TENSOR_PARALLEL_SIZE:-$DEFAULT_TENSOR_PARALLEL_SIZE} +MAX_NUM_SEQS_VAL=${MAX_NUM_SEQS:-$DEFAULT_MAX_NUM_SEQS} +INCLUDE_ENFORCE_EAGER_FLAG=${ENFORCE_EAGER:-$DEFAULT_ENFORCE_EAGER} +INCLUDE_DISABLE_LOG_REQUESTS_FLAG=${DISABLE_LOG_REQUESTS:-$DEFAULT_DISABLE_LOG_REQUESTS} +INCLUDE_PREFIX_CACHING_FLAG=${PREFIX_CACHING:-$DEFAULT_PREFIX_CACHING} + +CMD_ARGS=() +CMD_ARGS+=(--host "$HOST_VAL") +CMD_ARGS+=(--port "$PORT_VAL") + +if [[ "$INCLUDE_ENFORCE_EAGER_FLAG" != "false" && "$INCLUDE_ENFORCE_EAGER_FLAG" != "0" ]]; then + CMD_ARGS+=(--enforce-eager) +fi +if [[ "$INCLUDE_DISABLE_LOG_REQUESTS_FLAG" != "false" && "$INCLUDE_DISABLE_LOG_REQUESTS_FLAG" != "0" ]]; then + CMD_ARGS+=(--disable-log-requests) +fi +if [[ "$INCLUDE_PREFIX_CACHING_FLAG" != "false" && "$INCLUDE_PREFIX_CACHING_FLAG" != "0" ]]; then + CMD_ARGS+=(--enable-prefix-caching) +fi + +CMD_ARGS+=(--served-model-name "$SERVED_MODEL_NAME_VAL") +CMD_ARGS+=(--model "$MODEL_PATH_VAL") +CMD_ARGS+=(--max-model-len "$MAX_MODEL_LEN_VAL") +CMD_ARGS+=(--tensor-parallel-size "$TENSOR_PARALLEL_SIZE_VAL") +CMD_ARGS+=(--max-num-seqs "$MAX_NUM_SEQS_VAL") +CMD_ARGS+=(--trust-remote-code --dtype float16 --block-size 8192) +echo "--------------------------------------------------" +echo "Starting VLLM OpenAI API Server..." +echo "Using effective arguments:" +echo " Host (--host): $HOST_VAL" +echo " Port (--port): $PORT_VAL" +echo " Enforce Eager (--enforce-eager):" $([[ "$INCLUDE_ENFORCE_EAGER_FLAG" != "false" && "$INCLUDE_ENFORCE_EAGER_FLAG" != "0" ]] && echo "Enabled" || echo "Disabled (Env: ENFORCE_EAGER=$ENFORCE_EAGER)") +echo " Disable Log Req (--disable-log-requests):" $([[ "$INCLUDE_DISABLE_LOG_REQUESTS_FLAG" != "false" && "$INCLUDE_DISABLE_LOG_REQUESTS_FLAG" != "0" ]] && echo "Enabled" || echo "Disabled (Env: DISABLE_LOG_REQUESTS=$DISABLE_LOG_REQUESTS)") +echo " Served Model Name (--served-model-name): $SERVED_MODEL_NAME_VAL" +echo " Model Path (--model): $MODEL_PATH_VAL" +echo " Max Model Length (--max-model-len): $MAX_MODEL_LEN_VAL" +echo " Tensor Parallel Size (--tensor-parallel-size): $TENSOR_PARALLEL_SIZE_VAL" +echo " Max Num Seqs (--max-num-seqs): $MAX_NUM_SEQS_VAL" +echo "--------------------------------------------------" +echo "Full cmd:" +echo "python3 -m vllm.entrypoints.openai.api_server ${CMD_ARGS[*]}" +echo "--------------------------------------------------" + +python3 -m vllm.entrypoints.openai.api_server "${CMD_ARGS[@]}" +