发布时间:2026/6/24 2:59:45
Vllm 转 Ollama 接口
最新版本VisualStudio已经可以接入其他大语言模型了通过管理模型的接口进入设置但是他不支持其他的vllm、llama.cpp接口而且ollama接口也只支持本地lhttp://localhost:11434,其他不支持好像到以上位置这个点击添加按钮没啥用改地址也不行直接用大模型帮忙写一个脚本直接做接口转换把VS请求的localhost接口转到已经部署的vllm接口其他接口类似就行但是需要注意的是要实现完整的ollama接口#!/usr/bin/env python3 Ollama to vLLM 简单接口转发 import json import os import sys from datetime import datetime from fastapi import FastAPI, Request, HTTPException from fastapi.responses import StreamingResponse, JSONResponse import httpx # 配置 VLLM_URL http://172.16.1.15:8000 VLLM_API_KEY # 如果有 API key 填这里 OLLAMA_NAME qwen3.6-27b # 本地 Ollama 接口显示的模型名 VLLM_MODEL /data/ai/models/Qwen3.6-27B # vLLM 上的模型名 # app FastAPI() client httpx.AsyncClient(timeout300.0) def log_request(method, url, bodyNone, headersNone): 打印请求日志 print(f\n{*60}, flushTrue) print(f[{datetime.now().strftime(%H:%M:%S)}] {method} {url}, flushTrue) if headers: print(fHeaders: {json.dumps(headers, ensure_asciiFalse)}, flushTrue) if body: print(fBody: {json.dumps(body, ensure_asciiFalse, indent2)}, flushTrue) print(f{*60}\n, flushTrue) def log_response(status_code, dataNone): 打印响应日志 print(f[{datetime.now().strftime(%H:%M:%S)}] Response: {status_code}, flushTrue) if data: print(fData: {json.dumps(data, ensure_asciiFalse, indent2)}, flushTrue) print(f{*60}\n, flushTrue) app.get(/api/tags) async def get_models(): 获取模型列表 - 直接调用 vLLM url f{VLLM_URL}/v1/models log_request(GET, url) resp await client.get(url) log_response(resp.status_code, resp.json()) if resp.status_code ! 200: return {models: [{name: OLLAMA_NAME, model: OLLAMA_NAME}]} data resp.json() models [] for m in data.get(data, []): max_len m.get(max_model_len, 131072) models.append({ name: OLLAMA_NAME, model: OLLAMA_NAME, modified_at: datetime.utcfromtimestamp(m.get(created, 0)).strftime(%Y-%m-%dT%H:%M:%S) 00:00, size: 0, digest: , details: { parent_model: m.get(parent, ) or , format: vllm, family: qwen3, families: [qwen3], parameter_size: 27B, quantization_level: FP16, context_length: max_len, embedding_length: 5120 }, capabilities: [vision, completion, tools] }) return {models: models if models else [{name: OLLAMA_NAME, model: OLLAMA_NAME}]} app.get(/api/ps) async def running_models(): 列出正在运行的模型 return {models: [{name: OLLAMA_NAME, model: OLLAMA_NAME}]} app.post(/api/show) async def show_model(request: Request): Ollama 模型信息接口 - 直接调用 vLLM url f{VLLM_URL}/v1/models log_request(GET, url) resp await client.get(url) log_response(resp.status_code, resp.json()) if resp.status_code ! 200: return {license: , modelfile: , parameters: } data resp.json() model_info data.get(data, [{}])[0] max_len model_info.get(max_model_len, 131072) # 构建参数字符串 params [ fmax_model_len: {max_len}, fcreated: {model_info.get(created, )}, fowned_by: {model_info.get(owned_by, )} ] return { license: , modelfile: fFROM {VLLM_MODEL}\n\nPARAMETER max_model_len {max_len}\n\nSYSTEM \\\You are a helpful assistant.\\\, parameters: \n.join(params), details: { parent_model: model_info.get(parent, ) or , format: vllm, family: qwen3, families: [qwen3], parameter_size: 27B, quantization_level: FP16, context_length: max_len, embedding_length: 5120 }, capabilities: [vision, completion, tools] } app.post(/api/chat) async def chat(request: Request): 聊天接口 - Ollama 格式转 vLLM 格式支持工具调用和图像理解 body await request.json() messages body.get(messages, []) stream body.get(stream, False) vllm_request { model: VLLM_MODEL, messages: messages, temperature: body.get(temperature, 1.0), top_p: body.get(top_p, 1.0), stream: stream } # 支持工具调用 if body.get(tools): vllm_request[tools] body[tools] # 支持工具结果 if body.get(tool_choice): vllm_request[tool_choice] body[tool_choice] # 支持响应格式 if body.get(response_format): vllm_request[response_format] body[response_format] if body.get(max_tokens): vllm_request[max_tokens] body[max_tokens] headers {Content-Type: application/json} if VLLM_API_KEY: headers[Authorization] fBearer {VLLM_API_KEY} if stream: log_request(POST, f{VLLM_URL}/v1/chat/completions, vllm_request, headers) return StreamingResponse( stream_response(vllm_request, headers), media_typeapplication/x-ndjson ) else: log_request(POST, f{VLLM_URL}/v1/chat/completions, vllm_request, headers) resp await client.post(f{VLLM_URL}/v1/chat/completions, jsonvllm_request, headersheaders) log_response(resp.status_code, resp.json()) if resp.status_code ! 200: raise HTTPException(status_coderesp.status_code, detailresp.text) data resp.json() choice data[choices][0] result { model: OLLAMA_NAME, message: {role: assistant, content: choice[message][content]}, done: True } # 支持工具调用返回 if choice[message].get(tool_calls): result[message][tool_calls] choice[message][tool_calls] return result async def stream_response(vllm_request, headers): 流式响应 log_request(POST, f{VLLM_URL}/v1/chat/completions, vllm_request, headers) async with client.stream(POST, f{VLLM_URL}/v1/chat/completions, jsonvllm_request, headersheaders) as resp: print(f[{datetime.now().strftime(%H:%M:%S)}] 流式响应状态: {resp.status_code}, flushTrue) async for line in resp.aiter_lines(): if line.startswith(data: ): data line[6:] if data [DONE]: yield {done:true}\n break try: chunk json.loads(data) content chunk[choices][0].get(delta, {}).get(content, ) if content: yield json.dumps({model: OLLAMA_NAME, message: {role: assistant, content: content}, done: False}) \n except (json.JSONDecodeError, KeyError): continue app.post(/api/generate) async def generate(request: Request): 文本生成接口 body await request.json() vllm_request { model: VLLM_MODEL, prompt: body.get(prompt, ), temperature: body.get(temperature, 1.0), top_p: body.get(top_p, 1.0), stream: body.get(stream, False) } headers {Content-Type: application/json} if VLLM_API_KEY: headers[Authorization] fBearer {VLLM_API_KEY} if body.get(stream): log_request(POST, f{VLLM_URL}/v1/completions, vllm_request, headers) return StreamingResponse( stream_generate(vllm_request, headers), media_typeapplication/x-ndjson ) else: log_request(POST, f{VLLM_URL}/v1/completions, vllm_request, headers) resp await client.post(f{VLLM_URL}/v1/completions, jsonvllm_request, headersheaders) log_response(resp.status_code, resp.json()) if resp.status_code ! 200: raise HTTPException(status_coderesp.status_code, detailresp.text) data resp.json() return { model: OLLAMA_NAME, response: data[choices][0][text], done: True } async def stream_generate(vllm_request, headers): 流式生成 log_request(POST, f{VLLM_URL}/v1/completions, vllm_request, headers) async with client.stream(POST, f{VLLM_URL}/v1/completions, jsonvllm_request, headersheaders) as resp: print(f[{datetime.now().strftime(%H:%M:%S)}] 流式生成状态: {resp.status_code}, flushTrue) async for line in resp.aiter_lines(): if line.startswith(data: ): data line[6:] if data [DONE]: yield {done:true}\n break try: chunk json.loads(data) text chunk[choices][0].get(text, ) if text: yield json.dumps({model: OLLAMA_NAME, response: text, done: False}) \n except (json.JSONDecodeError, KeyError): continue app.post(/api/embed) async def embed(request: Request): 生成文本嵌入向量 - 调用 vLLM body await request.json() inputs body.get(input, []) if not isinstance(inputs, list): inputs [inputs] headers {Content-Type: application/json} if VLLM_API_KEY: headers[Authorization] fBearer {VLLM_API_KEY} vllm_body {model: VLLM_MODEL, input: inputs} log_request(POST, f{VLLM_URL}/v1/embeddings, vllm_body, headers) resp await client.post( f{VLLM_URL}/v1/embeddings, jsonvllm_body, headersheaders ) log_response(resp.status_code, resp.json()) if resp.status_code ! 200: raise HTTPException(status_coderesp.status_code, detailresp.text) data resp.json() embeddings [item.get(embedding, []) for item in data.get(data, [])] return {embeddings: embeddings} app.post(/api/embeddings) async def embeddings(request: Request): 旧版嵌入接口 - 调用 vLLM body await request.json() prompt body.get(prompt, ) headers {Content-Type: application/json} if VLLM_API_KEY: headers[Authorization] fBearer {VLLM_API_KEY} vllm_body {model: VLLM_MODEL, input: prompt} log_request(POST, f{VLLM_URL}/v1/embeddings, vllm_body, headers) resp await client.post( f{VLLM_URL}/v1/embeddings, jsonvllm_body, headersheaders ) log_response(resp.status_code, resp.json()) if resp.status_code ! 200: raise HTTPException(status_coderesp.status_code, detailresp.text) data resp.json() embedding data.get(data, [{}])[0].get(embedding, []) return {embedding: embedding} app.post(/v1/chat/completions) async def v1_chat(request: Request): OpenAI 格式接口 - 直接透传到 vLLM body await request.json() body[model] VLLM_MODEL headers {Content-Type: application/json} if VLLM_API_KEY: headers[Authorization] fBearer {VLLM_API_KEY} if body.get(stream, False): log_request(POST, f{VLLM_URL}/v1/chat/completions, body, headers) return StreamingResponse( stream_v1_chat(body, headers), media_typetext/event-stream ) else: log_request(POST, f{VLLM_URL}/v1/chat/completions, body, headers) resp await client.post(f{VLLM_URL}/v1/chat/completions, jsonbody, headersheaders) log_response(resp.status_code, resp.json()) if resp.status_code ! 200: raise HTTPException(status_coderesp.status_code, detailresp.text) return resp.json() async def stream_v1_chat(body, headers): OpenAI 格式流式响应 log_request(POST, f{VLLM_URL}/v1/chat/completions, body, headers) async with client.stream(POST, f{VLLM_URL}/v1/chat/completions, jsonbody, headersheaders) as resp: print(f[{datetime.now().strftime(%H:%M:%S)}] v1 流式响应状态: {resp.status_code}, flushTrue) async for line in resp.aiter_lines(): yield line \n app.post(/v1/completions) async def v1_completions(request: Request): OpenAI 格式补全接口 - 直接透传到 vLLM body await request.json() body[model] VLLM_MODEL headers {Content-Type: application/json} if VLLM_API_KEY: headers[Authorization] fBearer {VLLM_API_KEY} log_request(POST, f{VLLM_URL}/v1/completions, body, headers) resp await client.post(f{VLLM_URL}/v1/completions, jsonbody, headersheaders) log_response(resp.status_code, resp.json()) if resp.status_code ! 200: raise HTTPException(status_coderesp.status_code, detailresp.text) return resp.json() app.get(/v1/models) async def v1_models(): OpenAI 格式模型列表 url f{VLLM_URL}/v1/models log_request(GET, url) resp await client.get(url) log_response(resp.status_code, resp.json()) return resp.json() if __name__ __main__: import uvicorn print(启动 Ollama 代理: http://127.0.0.1:11434) print(f转发到 vLLM: {VLLM_URL}) uvicorn.run(app, host0.0.0.0, port11434)运行以上代码 python main.py然后回到VS自带模型点击添加出现实现的模型接口勾选模型点击保存就可以通过模型选择进行指定刚才设置的模型了

相关新闻

BitCloud ZigBee数据分片与节点参数配置实战指南
2026/6/24 1:59:45

BitCloud ZigBee数据分片与节点参数配置实战指南

1. 项目概述:为什么需要关注数据分片与节点参数?如果你正在用BitCloud这个ZigBee协议栈做开发,尤其是涉及到需要传输的数据量稍微大一点,或者网络里节点一多起来,大概率会遇到两个让人头疼的问题:一是数据包…

阅读更多
ZigBee 3.0开发实战:BDB、ZCL与ZGP核心组件详解
2026/6/24 1:59:45

ZigBee 3.0开发实战:BDB、ZCL与ZGP核心组件详解

1. 项目概述:从协议栈到应用,一次搞懂ZigBee 3.0开发如果你正在接触智能家居、工业传感网络或者任何需要低功耗、自组网无线通信的项目,ZigBee这个名字你肯定绕不开。而ZigBee 3.0作为目前的主流统一标准,它把过去各自为政的ZigBe…

阅读更多
嵌入式固件升级实战:基于FLIP工具与Atmel芯片的加密认证与传感器调试
2026/6/24 1:59:45

嵌入式固件升级实战:基于FLIP工具与Atmel芯片的加密认证与传感器调试

1. 项目概述:为什么我们需要升级固件?最近在整理一个老项目,里面用到了Atmel(现在应该叫Microchip了)的加密认证芯片和配套的温度传感器。这套东西当年设计得挺精巧,但固件版本太老,导致一些新功…

阅读更多
微电网控制柜选型5大误区,90%项目都踩过
2026/6/24 2:59:45

微电网控制柜选型5大误区,90%项目都踩过

在零碳园区微电网项目落地中,微电网协调控制柜看似是末端硬件设备,实则是决定整套微网能否稳定运行、节能增效、合规达标的核心关键。很多园区、工程方、采购方将重心放在光伏、储能、充电桩等主力设备上,对控制柜选型草草决策,凭…

阅读更多
从 OpenRouter 到 Vapeur AI:多模型统一接入为什么会成为开发标配?
2026/6/24 2:59:45

从 OpenRouter 到 Vapeur AI:多模型统一接入为什么会成为开发标配?

OpenRouter真正吸引人的地方,并不只是“能用更多模型”,而是解决了一个越来越现实的问题:AI 应用正在从调用单一模型,走向管理一组模型能力。今天做 AI 应用,开发者通常不会只依赖一个模型。日常问答、复杂推理、AI Co…

阅读更多
Minecraft世界转换终极指南:如何用Chunker实现跨平台存档共享
2026/6/24 2:59:45

Minecraft世界转换终极指南:如何用Chunker实现跨平台存档共享

Minecraft世界转换终极指南:如何用Chunker实现跨平台存档共享 【免费下载链接】Chunker Convert Minecraft worlds between Java Edition and Bedrock Edition 项目地址: https://gitcode.com/gh_mirrors/chu/Chunker 作为Minecraft玩家,您是否曾…

阅读更多
多智能体推演:香港黄金清算系统7月上线,银行备货400盎司金条的底层逻辑——因果推断模型
2026/6/24 2:59:45

多智能体推演:香港黄金清算系统7月上线,银行备货400盎司金条的底层逻辑——因果推断模型

摘要:本文通过构建黄金市场基础设施分析模型,结合香港黄金中央清算系统上线进程、伦敦合格交割标准(London Good Delivery)、亚洲黄金流动性分布以及区域金融中心竞争格局,分析香港建立本土黄金清算网络对亚洲黄金定价…

阅读更多
Vllm 转 Ollama 接口
2026/6/24 2:59:45

Vllm 转 Ollama 接口

最新版本VisualStudio已经可以接入其他大语言模型了,通过管理模型的接口进入设置 但是他不支持其他的vllm、llama.cpp接口 而且ollama接口也只支持本地lhttp://localhost:11434,其他不支持好像 到以上位置,这个点击添加按钮没啥用,改地址也…

阅读更多
BitCloud ZigBee数据分片与节点参数配置实战指南
2026/6/24 1:59:45

BitCloud ZigBee数据分片与节点参数配置实战指南

1. 项目概述:为什么需要关注数据分片与节点参数?如果你正在用BitCloud这个ZigBee协议栈做开发,尤其是涉及到需要传输的数据量稍微大一点,或者网络里节点一多起来,大概率会遇到两个让人头疼的问题:一是数据包…

阅读更多
嵌入式语音编解码实战:G.726 ADPCM库集成与优化指南
2026/6/23 3:25:21

嵌入式语音编解码实战:G.726 ADPCM库集成与优化指南

1. 项目概述与G.726 ADPCM技术背景在嵌入式语音处理领域,带宽和存储资源往往是寸土寸金的。如果你做过对讲机、VoIP网关或者早期的数字录音设备,一定对如何在有限的比特率下保住语音可懂度这件事深有感触。我当年接手一个车载调度系统的项目,…

阅读更多
ITU656格式化器寄存器配置实战:VBI数据处理与VCR特技播放兼容性
2026/6/23 4:51:28

ITU656格式化器寄存器配置实战:VBI数据处理与VCR特技播放兼容性

1. 项目概述与核心挑战在数字视频处理领域,将原始的视频数据、同步时序以及各种辅助信息打包成一个标准、稳定的串行数据流,是确保设备间互联互通的基础。ITU-R BT.656标准(常简称为ITU656)正是为此而生的一套“交通规则”。它定义…

阅读更多
嵌入式GUI开发实战:emWin环境搭建、配置优化与性能调优指南
2026/6/23 0:40:11

嵌入式GUI开发实战:emWin环境搭建、配置优化与性能调优指南

1. 项目概述与emWin核心价值解析在嵌入式系统开发领域,人机交互(HMI)的设计正从简单的LED指示灯和按键,快速向全彩图形化界面演进。无论是智能家电上的触摸屏、工业PLC的操作面板,还是医疗设备的参数显示,一…

阅读更多
TaskJuggler脚本编程入门:用代码实现自动化项目管理
2026/6/24 0:59:45

TaskJuggler脚本编程入门:用代码实现自动化项目管理

TaskJuggler脚本编程入门:用代码实现自动化项目管理 【免费下载链接】TaskJuggler TaskJuggler - Project Management beyond Gantt chart drawing 项目地址: https://gitcode.com/gh_mirrors/ta/TaskJuggler TaskJuggler是一款强大的开源项目管理工具&#…

阅读更多
BitCloud SDK实战:SAMR21与ATmegaRFR2 Zigbee节点固件烧录与配置指南
2026/6/24 1:59:45

BitCloud SDK实战:SAMR21与ATmegaRFR2 Zigbee节点固件烧录与配置指南

1. 从零开始的无线节点搭建:为什么是BitCloud、SAMR21与ATmegaRFR2?如果你正在物联网领域,特别是Zigbee相关的项目中摸索,那么“BitCloud SDK”这个名字你大概率不会陌生。它不是一个新潮的框架,但却是许多经典Zigbee设…

阅读更多
2026年GEO信源媒体发稿平台全盘点:三种模式、代表玩家与适用场景
2026/6/24 1:59:45

2026年GEO信源媒体发稿平台全盘点:三种模式、代表玩家与适用场景

2025年以来,生成式人工智能正在深刻重塑信息入口与用户决策方式。麦肯锡发布的研究数据显示,约50%的消费者已在使用AI驱动搜索,其中44%将其视为首选信息来源。与此同时,Google搜索中已有约50%的结果呈现AI摘要,预计到2…

阅读更多
GIT修改用户名
2026/6/23 8:19:27

GIT修改用户名

在GIT中修改用户名可按以下步骤操作: 查看当前git的用户名,使用命令git config --list或git config user.name。修改git用户名,使用命令git config --global user.name "xxx(新的用户名)",将其中…

阅读更多
Win11Debloat:让你的Windows系统重获新生的终极优化工具
2026/6/23 23:39:46

Win11Debloat:让你的Windows系统重获新生的终极优化工具

Win11Debloat:让你的Windows系统重获新生的终极优化工具 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and …

阅读更多
技术深度解析:m4s-converter实现原理与B站缓存视频转换最佳实践
2026/6/23 6:37:14

技术深度解析:m4s-converter实现原理与B站缓存视频转换最佳实践

技术深度解析:m4s-converter实现原理与B站缓存视频转换最佳实践 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter m4s-converter是一个…

阅读更多