Ubuntu部署ktransformers

準備工作

一臺服務器

CPU:500G

GPU:48G(NVIDIA4090)

系統:Ubuntu20.04(github的文檔好像用的是22.04)

第一步:下載權重文件

1.下載hfd

wget https://hf-mirror.com/hfd/hfd.sh
chmod a+x hfd.sh

2.設置環境變量

export HF_ENDPOINT=https://hf-mirror.com

3.下載模型(需要梯子,需要帶上huggingface的token)

./hfd.sh gpt2

4.下載數據集(需要梯子,需要帶上huggingface的token)

./hfd.sh wikitext --dataset

5.下載大文件(需要梯子,文件很大,大約四五百G)

./hfd.sh unsloth/DeepSeek-R1-GGUF --include DeepSeek-R1-Q4_K_M/*

第二步:拉代碼,編譯代碼

1.使用Anaconda3安裝Python3.11

conda create --name ktransformers python=3.11
conda activate ktransformers 
conda install -c conda-forge libstdcxx-ng

2.安裝其他依賴

pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126
pip3 install packaging ninja cpufeature numpy
sudo add-apt-repository ppa: ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install --only-upgrade libstdc++6
pip install flash-attn --no-build-isolation

3.查看顯卡版本及cuda版本

以下兩條指令顯示的CUDA版本需要一致,若不一致,系統會以nvcc --version的為準

nvcc --version
nvidia-smi

4.拉代碼

git clone https://github.com/kvcache-ai/ktransformers.git

cd ktransformers

git submodule init

git submodule update

5.編譯

export USE_NUMA=1
make dev_install

第三部:運行

python ktransformers/local_chat.py --model_path deepseek-ai/DeepSeek-R1 --gguf_path /home/dpkj/deepseek/DeepSeek-R1-GGUF/DeepSeek-R1-Q4_K_M/ --cpu_infer 50 --cache_lens 1536 --max_new_tokens 8192

# --model_path:模型位置,不需要修改
# --gguf_path:前面下載的大文件,模型文件位置,按照實際情況而定
# --cpu_infer:CPU占用,單位百分比,如果服務器不死DDR5雙路CPU,可以適量調低此占比

其他啟動參數

python -m transformers.local_chat --model_path deepseek-ai/DeepSeek-R1 --gguf_path /root/DeepSeek-R1-GGUF/DeepSeek-R1-Q4_K_M/ --cpu_infer 53 --cache_lens 1536

python ./transformers/local_chat.py --model_path deepseek-ai/DeepSeek-R1 --gguf_path /home/shadeform/DeepSeek-R1-GGUF/DeepSeek-R1-Q4 K M/ --cpu_infer 53 --cache_lens 1536 --optimize_config_path transformers/optimize/optimize_rules/DeepSeek-V3-Chat-multi-gpu-marlin.yaml

python -m transformers.local_chat --model_path deepseek-ai/DeepSeek-R1 --gguf_path /root/autodi-tmp/DeepSeek-R1-GGUF/DeepSeek-R1-Q4 K M/ --cpu_infer 128 --cache_lens 1536 --max_new_tokens 8192 --optimize_config_path ./transformers/optimize/optimize_rules/DeepSeek-V3-Chat-multi-gpu-marlin-4.yaml

transformers --model_path deepseek-ai/DeepSeek-R1 --gguf_path /root/autodi-tmp/DeepSeek-R1-GGUF/DeepSeek-R1-Q4 K M/ --cpu_infer 65 --cache_lens 1536 --max_new_tokens 8192 --port 6006 --optimize_config_path /transformers/optimize/optimize_rules/DeepSeek-V3-Chat-multi-gpu-marlin-4.yaml

curl -X 'POST"
?? ?"http://localhost:6006/v1/chat/completions'\
?? ?-H 'accept: application/json' \
?? ?-H 'Content-Type: application/json' \
?? ?-d'{
?? ??? ?"messages": [
?? ??? ?"content": "tell a joke",
?? ??? ?"role": "user"
?? ?],
?? ?"model": "ktranformers-model",
?? ?"stream": true
}'

外傳

1. 使用API方式調用

新建文件:chat_openai.py

import argparse
import uvicorn
from typing import List, Dict, Optional, Any
from fastapi import FastAPI, HTTPException, status
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import os
import sys
import time
from fastapi import Request
from fastapi.responses import StreamingResponse, JSONResponse
import json
import logging

# 設置日志記錄
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

project_dir = os.path.dirname(os.path.dirname(__file__))
sys.path.insert(0, project_dir)
import torch
from transformers import (
? ? AutoTokenizer,
? ? AutoConfig,
? ? AutoModelForCausalLM,
? ? GenerationConfig,
? ? TextStreamer,
)
from ktransformers.optimize.optimize import optimize_and_load_gguf
from ktransformers.models.modeling_deepseek import DeepseekV2ForCausalLM
from ktransformers.models.modeling_qwen2_moe import Qwen2MoeForCausalLM
from ktransformers.models.modeling_deepseek_v3 import DeepseekV3ForCausalLM
from ktransformers.models.modeling_llama import LlamaForCausalLM
from ktransformers.models.modeling_mixtral import MixtralForCausalLM
from ktransformers.util.utils import prefill_and_generate
from ktransformers.server.config.config import Config

custom_models = {
? ? "DeepseekV2ForCausalLM": DeepseekV2ForCausalLM,
? ? "DeepseekV3ForCausalLM": DeepseekV3ForCausalLM,
? ? "Qwen2MoeForCausalLM": Qwen2MoeForCausalLM,
? ? "LlamaForCausalLM": LlamaForCausalLM,
? ? "MixtralForCausalLM": MixtralForCausalLM,
}

ktransformer_rules_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "optimize", "optimize_rules")
default_optimize_rules = {
? ? "DeepseekV2ForCausalLM": os.path.join(ktransformer_rules_dir, "DeepSeek-V2-Chat.yaml"),
? ? "DeepseekV3ForCausalLM": os.path.join(ktransformer_rules_dir, "DeepSeek-V3-Chat.yaml"),
? ? "Qwen2MoeForCausalLM": os.path.join(ktransformer_rules_dir, "Qwen2-57B-A14B-Instruct.yaml"),
? ? "LlamaForCausalLM": os.path.join(ktransformer_rules_dir, "Internlm2_5-7b-Chat-1m.yaml"),
? ? "MixtralForCausalLM": os.path.join(ktransformer_rules_dir, "Mixtral.yaml"),
}

# 全局變量,存儲初始化后的模型
chat_model = None

class OpenAIChat:
? ? def __init__(
? ? ? ? self,
? ? ? ? model_path: str,
? ? ? ? optimize_rule_path: str = None,
? ? ? ? gguf_path: str = None,
? ? ? ? cpu_infer: int = Config().cpu_infer,
? ? ? ? use_cuda_graph: bool = True,
? ? ? ? mode: str = "normal",
? ? ):
? ? ? ? torch.set_grad_enabled(False)
? ? ? ? Config().cpu_infer = cpu_infer

? ? ? ? self.tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
? ? ? ? config = AutoConfig.from_pretrained(model_path, trust_remote_code=True)
? ? ? ? self.streamer = TextStreamer(self.tokenizer, skip_prompt=True) if not Config().cpu_infer else None
? ? ? ? if mode == 'long_context':
? ? ? ? ? ? assert config.architectures[0] == "LlamaForCausalLM", "Only LlamaForCausalLM supports long_context mode"
? ? ? ? ? ? torch.set_default_dtype(torch.float16)
? ? ? ? else:
? ? ? ? ? ? torch.set_default_dtype(config.torch_dtype)

? ? ? ? with torch.device("meta"):
? ? ? ? ? ? if config.architectures[0] in custom_models:
? ? ? ? ? ? ? ? if "Qwen2Moe" in config.architectures[0]:
? ? ? ? ? ? ? ? ? ? config._attn_implementation = "flash_attention_2"
? ? ? ? ? ? ? ? if "Llama" in config.architectures[0]:
? ? ? ? ? ? ? ? ? ? config._attn_implementation = "eager"
? ? ? ? ? ? ? ? if "Mixtral" in config.architectures[0]:
? ? ? ? ? ? ? ? ? ? config._attn_implementation = "flash_attention_2"
? ? ? ? ? ? ? ? model = custom_models[config.architectures[0]](config)
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? model = AutoModelForCausalLM.from_config(
? ? ? ? ? ? ? ? ? ? config, trust_remote_code=True, attn_implementation="flash_attention_2"
? ? ? ? ? ? ? ? )

? ? ? ? if optimize_rule_path is None:
? ? ? ? ? ? if config.architectures[0] in default_optimize_rules:
? ? ? ? ? ? ? ? optimize_rule_path = default_optimize_rules[config.architectures[0]]

? ? ? ? optimize_and_load_gguf(model, optimize_rule_path, gguf_path, config)
? ? ? ??
? ? ? ? try:
? ? ? ? ? ? model.generation_config = GenerationConfig.from_pretrained(model_path)
? ? ? ? except:
? ? ? ? ? ? model.generation_config = GenerationConfig(
? ? ? ? ? ? ? ? max_length=128,
? ? ? ? ? ? ? ? temperature=0.7,
? ? ? ? ? ? ? ? top_p=0.9,
? ? ? ? ? ? ? ? do_sample=True
? ? ? ? ? ? )
? ? ? ??
? ? ? ? if model.generation_config.pad_token_id is None:
? ? ? ? ? ? model.generation_config.pad_token_id = model.generation_config.eos_token_id
? ? ? ??
? ? ? ? model.eval()
? ? ? ? self.model = model
? ? ? ? self.use_cuda_graph = use_cuda_graph
? ? ? ? self.mode = mode
? ? ? ? logger.info("Model loaded successfully!")

? ? def create_chat_completion(
? ? ? ? self,
? ? ? ? messages: List[Dict[str, str]],
? ? ? ? temperature: float = 0.7,
? ? ? ? max_tokens: int = 1000,
? ? ? ? top_p: float = 0.9,
? ? ? ? force_think: bool = False,
? ? ) -> Dict:
? ? ? ? input_tensor = self.tokenizer.apply_chat_template(
? ? ? ? ? ? messages, add_generation_prompt=True, return_tensors="pt"
? ? ? ? )
? ? ? ??
? ? ? ? if force_think:
? ? ? ? ? ? token_thinks = torch.tensor([self.tokenizer.encode("<think>\\n", add_special_tokens=False)],
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? device=input_tensor.device)
? ? ? ? ? ? input_tensor = torch.cat([input_tensor, token_thinks], dim=1)

? ? ? ? generation_config = GenerationConfig(
? ? ? ? ? ? temperature=temperature,
? ? ? ? ? ? top_p=top_p,
? ? ? ? ? ? max_new_tokens=max_tokens,
? ? ? ? ? ? do_sample=True ?# Ensure do_sample is True if using temperature or top_p
? ? ? ? )

? ? ? ? generated = prefill_and_generate(
? ? ? ? ? ? self.model,
? ? ? ? ? ? self.tokenizer,
? ? ? ? ? ? input_tensor.cuda(),
? ? ? ? ? ? max_tokens,
? ? ? ? ? ? self.use_cuda_graph,
? ? ? ? ? ? self.mode,
? ? ? ? ? ? force_think
? ? ? ? )

? ? ? ? # Convert token IDs to text
? ? ? ? generated_text = self.tokenizer.decode(generated, skip_special_tokens=True)

? ? ? ? return {
? ? ? ? ? ? "choices": [{
? ? ? ? ? ? ? ? "message": {
? ? ? ? ? ? ? ? ? ? "role": "assistant",
? ? ? ? ? ? ? ? ? ? "content": generated_text
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }],
? ? ? ? ? ? "usage": {
? ? ? ? ? ? ? ? "prompt_tokens": input_tensor.shape[1],
? ? ? ? ? ? ? ? "completion_tokens": len(generated),
? ? ? ? ? ? ? ? "total_tokens": input_tensor.shape[1] + len(generated)
? ? ? ? ? ? }
? ? ? ? }

class ChatMessage(BaseModel):
? ? role: str
? ? content: str

class ChatCompletionRequest(BaseModel):
? ? messages: List[ChatMessage] ?# 確保 messages 是 Pydantic 模型實例的列表
? ? model: str = "default-model"
? ? temperature: Optional[float] = 0.7
? ? top_p: Optional[float] = 0.9
? ? max_tokens: Optional[int] = 1000
? ? stream: Optional[bool] = False
? ? force_think: Optional[bool] = True

class ChatCompletionResponse(BaseModel):
? ? id: str = "chatcmpl-default"
? ? object: str = "chat.completion"
? ? created: int = 0
? ? model: str = "default-model"
? ? choices: List[Dict[str, Any]]
? ? usage: Dict[str, int]

app = FastAPI(title="KVCache.AI API Server")

@app.get("/health")
async def health_check():
? ? return {"status": "healthy"}

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
? ? start_time = time.time()
? ? response = await call_next(request)
? ? process_time = time.time() - start_time
? ? response.headers["X-Process-Time"] = f"{process_time:.4f}s"
? ? return response

app.add_middleware(
? ? CORSMiddleware,
? ? allow_origins=["*"],
? ? allow_credentials=True,
? ? allow_methods=["*"],
? ? allow_headers=["*"],
)

@app.post("/v1/chat/completions", response_model=ChatCompletionResponse)
async def chat_completion(request: ChatCompletionRequest):
? ? try:
? ? ? ? # 如果 messages 是 Pydantic 模型實例列表,使用 model_dump
? ? ? ? messages = [m.model_dump() for m in request.messages]
? ? ? ? response = chat_model.create_chat_completion(
? ? ? ? ? ? messages=messages,
? ? ? ? ? ? temperature=request.temperature,
? ? ? ? ? ? max_tokens=request.max_tokens,
? ? ? ? ? ? top_p=request.top_p,
? ? ? ? ? ? force_think=request.force_think
? ? ? ? )

? ? ? ? return {
? ? ? ? ? ? "id": f"chatcmpl-{int(time.time())}",
? ? ? ? ? ? "object": "chat.completion",
? ? ? ? ? ? "created": int(time.time()),
? ? ? ? ? ? "model": request.model,
? ? ? ? ? ? "choices": [{
? ? ? ? ? ? ? ? "index": 0,
? ? ? ? ? ? ? ? "message": {
? ? ? ? ? ? ? ? ? ? "role": "assistant",
? ? ? ? ? ? ? ? ? ? "content": response['choices'][0]['message']['content']
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? "finish_reason": "stop"
? ? ? ? ? ? }],
? ? ? ? ? ? "usage": response['usage']
? ? ? ? }
? ? except Exception as e:
? ? ? ? logger.error(f"API Error: {str(e)}")
? ? ? ? raise HTTPException(
? ? ? ? ? ? status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
? ? ? ? ? ? detail=f"Internal server error: {str(e)}"
? ? ? ? )

def create_app(model_path: str, gguf_path: str, cpu_infer:int, optimize_rule_path: Optional[str] = None):
? ? global chat_model
? ? chat_model = OpenAIChat(
? ? ? ? model_path=model_path,
? ? ? ? gguf_path=gguf_path,
? ? ? ? optimize_rule_path=optimize_rule_path,
? ? ? ? cpu_infer=cpu_infer
? ? )
? ? return app

def main():
? ? parser = argparse.ArgumentParser(description="KVCache.AI API Server")
? ? parser.add_argument("--model_path", type=str, required=True, help="HuggingFace模型路徑")
? ? parser.add_argument("--gguf_path", type=str, required=True, help="GGUF模型文件路徑")
? ? parser.add_argument("--optimize_rule_path", type=str, help="優化規則文件路徑")
? ? parser.add_argument("--port", type=int, default=8000, help="服務端口號")
? ? parser.add_argument("--cpu_infer", type=int, default=10, help="使用cpu數量")
? ? parser.add_argument("--host", type=str, default="0.0.0.0", help="綁定地址")
? ? args = parser.parse_args()

? ? create_app(
? ? ? ? model_path=args.model_path,
? ? ? ? gguf_path=args.gguf_path,
? ? ? ? optimize_rule_path=args.optimize_rule_path,
? ? ? ? cpu_infer=args.cpu_infer
? ? )

? ? uvicorn.run(
? ? ? ? app,
? ? ? ? host=args.host,
? ? ? ? port=args.port,
? ? ? ? loop="uvloop",
? ? ? ? http="httptools",
? ? ? ? timeout_keep_alive=300,
? ? ? ? log_level="info",
? ? ? ? access_log=False
? ? )

if __name__ == "__main__":
? ? main()

文件防止位置:

安裝依賴:

pip install protobuf uvicorn httptools
pip install uvloop

啟動:

python ktransformers/chat_openai.py --model_path deepseek-ai/DeepSeek-R1 --gguf_path /home/dpkj/deepseek/DeepSeek-R1-GGUF/DeepSeek-R1-Q4_K_M/

2.使用open-WEBUI進行可視化對接

# 使用Pip下載OPEN-WEBUI

pip install open-webui
# 下載完成后開啟服務
open-webui serve
#啟動成功如下
在OPEN-WebUI

import os
import json
import requests
from pydantic import BaseModel, Field
from typing import List, Union, Iterator

# Set DEBUG to True to enable detailed logging
DEBUG = False


class Pipe:
? ? class Valves(BaseModel):
? ? ? ? openai_API_KEY: str = Field(default="none") ?# Optional API key if needed
? ? ? ? DEFAULT_MODEL: str = Field(default="DeepSeek-R1") ?# Default model identifier

? ? def __init__(self):
? ? ? ? self.id = "DeepSeek-R1"
? ? ? ? self.type = "manifold"
? ? ? ? self.name = "KT: "
? ? ? ? self.valves = self.Valves(
? ? ? ? ? ? **{
? ? ? ? ? ? ? ? "openai_API_KEY": os.getenv("openai_API_KEY", "none"),
? ? ? ? ? ? ? ? "DEFAULT_MODEL": os.getenv("openai_DEFAULT_MODEL", "DeepSeek-R1"),
? ? ? ? ? ? }
? ? ? ? )
? ? ? ? # Self-hosted FastAPI server details
? ? ? ? self.api_url = (
? ? ? ? ? ? "http://localhost:8000/v1/chat/completions" ?# FastAPI server endpoint
? ? ? ? )
? ? ? ? self.headers = {"Content-Type": "application/json"}

? ? def get_openai_models(self):
? ? ? ? """Return available models - for openai we'll return a fixed list"""
? ? ? ? return [{"id": "KT", "name": "DeepSeek-R1"}]

? ? def pipes(self) -> List[dict]:
? ? ? ? return self.get_openai_models()

? ? def pipe(self, body: dict) -> Union[str, Iterator[str]]:
? ? ? ? try:
? ? ? ? ? ? # Use default model ID since OpenAI has a single endpoint
? ? ? ? ? ? model_id = self.valves.DEFAULT_MODEL
? ? ? ? ? ? messages = []

? ? ? ? ? ? # Process messages including system, user, and assistant messages
? ? ? ? ? ? for message in body["messages"]:
? ? ? ? ? ? ? ? if isinstance(message.get("content"), list):
? ? ? ? ? ? ? ? ? ? # For OpenAI, we'll join multiple content parts into a single text
? ? ? ? ? ? ? ? ? ? text_parts = []
? ? ? ? ? ? ? ? ? ? for content in message["content"]:
? ? ? ? ? ? ? ? ? ? ? ? if content["type"] == "text":
? ? ? ? ? ? ? ? ? ? ? ? ? ? text_parts.append(content["text"])
? ? ? ? ? ? ? ? ? ? ? ? elif content["type"] == "image_url":
? ? ? ? ? ? ? ? ? ? ? ? ? ? # OpenAI might not support image inputs - add a note about the image
? ? ? ? ? ? ? ? ? ? ? ? ? ? text_parts.append(f"[Image: {content['image_url']['url']}]")
? ? ? ? ? ? ? ? ? ? messages.append(
? ? ? ? ? ? ? ? ? ? ? ? {"role": message["role"], "content": "".join(text_parts)}
? ? ? ? ? ? ? ? ? ? )
? ? ? ? ? ? ? ? else:
? ? ? ? ? ? ? ? ? ? # Handle simple text messages
? ? ? ? ? ? ? ? ? ? messages.append(
? ? ? ? ? ? ? ? ? ? ? ? {"role": message["role"], "content": message["content"]}
? ? ? ? ? ? ? ? ? ? )

? ? ? ? ? ? if DEBUG:
? ? ? ? ? ? ? ? print("FastAPI API request:")
? ? ? ? ? ? ? ? print(" Model:", model_id)
? ? ? ? ? ? ? ? print(" Messages:", json.dumps(messages, indent=2))

? ? ? ? ? ? # Prepare the API call parameters
? ? ? ? ? ? payload = {
? ? ? ? ? ? ? ? "model": model_id,
? ? ? ? ? ? ? ? "messages": messages,
? ? ? ? ? ? ? ? "temperature": body.get("temperature", 0.7),
? ? ? ? ? ? ? ? "top_p": body.get("top_p", 0.9),
? ? ? ? ? ? ? ? "max_tokens": body.get("max_tokens", 8192),
? ? ? ? ? ? ? ? "stream": body.get("stream", True),
? ? ? ? ? ? }

? ? ? ? ? ? # Add stop sequences if provided
? ? ? ? ? ? if body.get("stop"):
? ? ? ? ? ? ? ? payload["stop"] = body["stop"]

? ? ? ? ? ? # Sending request to local FastAPI server
? ? ? ? ? ? if body.get("stream", False):
? ? ? ? ? ? ? ? # Streaming response
? ? ? ? ? ? ? ? def stream_generator():
? ? ? ? ? ? ? ? ? ? try:
? ? ? ? ? ? ? ? ? ? ? ? response = requests.post(
? ? ? ? ? ? ? ? ? ? ? ? ? ? self.api_url,
? ? ? ? ? ? ? ? ? ? ? ? ? ? json=payload,
? ? ? ? ? ? ? ? ? ? ? ? ? ? headers=self.headers,
? ? ? ? ? ? ? ? ? ? ? ? ? ? stream=True,
? ? ? ? ? ? ? ? ? ? ? ? )
? ? ? ? ? ? ? ? ? ? ? ? for line in response.iter_lines():
? ? ? ? ? ? ? ? ? ? ? ? ? ? if line:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? yield line.decode("utf-8")
? ? ? ? ? ? ? ? ? ? except Exception as e:
? ? ? ? ? ? ? ? ? ? ? ? if DEBUG:
? ? ? ? ? ? ? ? ? ? ? ? ? ? print(f"Streaming error: {e}")
? ? ? ? ? ? ? ? ? ? ? ? yield f"Error during streaming: {str(e)}"

? ? ? ? ? ? ? ? return stream_generator()
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? # Regular response
? ? ? ? ? ? ? ? response = requests.post(
? ? ? ? ? ? ? ? ? ? self.api_url, json=payload, headers=self.headers
? ? ? ? ? ? ? ? )
? ? ? ? ? ? ? ? if response.status_code == 200:
? ? ? ? ? ? ? ? ? ? generated_content = (
? ? ? ? ? ? ? ? ? ? ? ? response.json()
? ? ? ? ? ? ? ? ? ? ? ? .get("choices", [{}])[0]
? ? ? ? ? ? ? ? ? ? ? ? .get("message", {})
? ? ? ? ? ? ? ? ? ? ? ? .get("content", "")
? ? ? ? ? ? ? ? ? ? )
? ? ? ? ? ? ? ? ? ? return generated_content
? ? ? ? ? ? ? ? else:
? ? ? ? ? ? ? ? ? ? return f"Error: {response.status_code}, {response.text}"
? ? ? ? except Exception as e:
? ? ? ? ? ? if DEBUG:
? ? ? ? ? ? ? ? print(f"Error in pipe method: {e}")
? ? ? ? ? ? return f"Error: {e}"

? ? def health_check(self) -> bool:
? ? ? ? """Check if the OpenAI API (local FastAPI service) is accessible"""
? ? ? ? try:
? ? ? ? ? ? # Simple health check with a basic prompt
? ? ? ? ? ? response = requests.post(
? ? ? ? ? ? ? ? self.api_url,
? ? ? ? ? ? ? ? json={
? ? ? ? ? ? ? ? ? ? "model": self.valves.DEFAULT_MODEL,
? ? ? ? ? ? ? ? ? ? "messages": [{"role": "user", "content": "Hello"}],
? ? ? ? ? ? ? ? ? ? "max_tokens": 5,
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? headers=self.headers,
? ? ? ? ? ? )
? ? ? ? ? ? return response.status_code == 200
? ? ? ? except Exception as e:
? ? ? ? ? ? if DEBUG:
? ? ? ? ? ? ? ? print(f"Health check failed: {e}")
? ? ? ? ? ? return False

完~
<script src="chrome-extension://bincmiainjofjnhchmcalkanjebghoen/aiscripts/script-main.js"></script>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/71531.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/71531.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/71531.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++初階——簡單實現vector

目錄 1、前言 2、Vector.h 3、Test.cpp 1、前言 簡單實現std::vector類模板。 相較于前面的string&#xff0c;vector要注意&#xff1a; 深拷貝&#xff0c;因為vector的元素可能是類類型&#xff0c;類類型元素可以通過賦值重載&#xff0c;自己實現深拷貝。 迭代器失效…

全志A133 android10 適配SLM770A 4G模塊

一&#xff0c;模塊基本信息 1.官方介紹 SLM770A是美格智能最新推出的一款LTE Cat.4無線通訊模組&#xff0c;最大支持下行速率150Mbps及上行速率50Mbps。同時向下兼容現有的3G和2G網絡&#xff0c;以確保即使在偏遠地區也可以進行網絡通信。 SLM770A模組支持分集接收和MIMO技…

微信小程序:多菜單欄設計效果

一、實現效果 二、代碼 wxml 編輯前端界面,步驟 菜單邏輯: 逐步取出數組中的項,首先取出頂部菜單項,然后選中后取出選中的底部數據(左側菜單+右側內容),然后點擊左側菜單取出選中的左側菜單對應的右側內容 ①這里我的數據是全部封裝到一個數組對象的,首先我的循環…

C++基礎知識學習記錄—string類

string實際上是C內置的一個類&#xff0c;內部對char *進行了封裝&#xff0c;不用擔心數組越界問題&#xff0c;string類中&#xff0c;除了上課講解的函數外&#xff0c;還有很多函數可以使用&#xff0c;可以自行查閱文檔。 構造函數原型&#xff1a; string(); //創建一個…

Ollama+DeepSeek+Open-WebUi

環境準備 Docker Ollama Open-WebUi Ollama 下載地址&#xff1a;Ollama docker安裝ollama docker run -d \ -v /data/ollama/data:/root/.ollama \ -p 11434:11434 \ --name ollama ollama/ollama 下載模型 Ollama模型倉庫 # 示例&#xff1a;安裝deepseek-r1:7b doc…

設計模式--訪問者模式【行為型模式】

設計模式的分類 我們都知道有 23 種設計模式&#xff0c;這 23 種設計模式可分為如下三類&#xff1a; 創建型模式&#xff08;5 種&#xff09;&#xff1a;單例模式、工廠方法模式、抽象工廠模式、建造者模式、原型模式。結構型模式&#xff08;7 種&#xff09;&#xff1…

前端循環全解析:JS/ES/TS 循環寫法與實戰示例

循環是編程中控制流程的核心工具。本文將詳細介紹 JavaScript、ES6 及 TypeScript 中各種循環的寫法、特性&#xff0c;并通過實際示例幫助你掌握它們的正確使用姿勢。 目錄 傳統三劍客 for 循環 while 循環 do...while 循環 ES6 新特性 forEach for...of for...in 數組…

數據中心儲能蓄電池狀態監測管理系統 組成架構介紹

安科瑞劉鴻鵬 摘要 隨著數據中心對供電可靠性要求的提高&#xff0c;蓄電池儲能系統成為關鍵的后備電源。本文探討了蓄電池監測系統在數據中心儲能系統中的重要性&#xff0c;分析了ABAT系列蓄電池在線監測系統的功能、技術特點及其應用優勢。通過蓄電池監測系統的實施&#…

Mac端homebrew安裝配置

拷打了一下午o3-mini-high&#xff0c;不如這位博主的超強帖子&#xff0c;10分鐘結束戰斗 跟隨該文章即可&#xff0c;2025/2/19親測可行 mac 安裝HomeBrew(100%成功)_mac安裝homebrew-CSDN博客文章瀏覽閱讀10w次&#xff0c;點贊258次&#xff0c;收藏837次。一直覺得自己寫…

機器學習實戰(8):降維技術——主成分分析(PCA)

第8集&#xff1a;降維技術——主成分分析&#xff08;PCA&#xff09; 在機器學習中&#xff0c;降維&#xff08;Dimensionality Reduction&#xff09; 是一種重要的數據處理技術&#xff0c;用于減少特征維度、去除噪聲并提高模型效率。主成分分析&#xff08;Principal C…

windows環境下用docker搭建php開發環境dnmp

安裝WSL WSL即Linux子系統&#xff0c;比虛擬機占用資源少&#xff0c;安裝的前提是系統必須是win10以上。 WSL的安裝比較簡單&#xff0c;網上有很多教程&#xff0c;例如&#xff1a;WSL簡介與安裝流程&#xff08;Windows 下的 Linux 子系統&#xff09;_wsl安裝-CSDN博客&…

Python網絡爬蟲技術詳解文檔

Python網絡爬蟲技術詳解文檔 目錄 網絡爬蟲概述爬蟲核心技術解析常用Python爬蟲庫實戰案例演示反爬蟲機制與應對策略爬蟲法律與道德規范高級爬蟲技術資源推薦與學習路徑1. 網絡爬蟲概述 1.1 什么是網絡爬蟲 網絡爬蟲(Web Crawler)是一種按特定規則自動抓取互聯網信息的程序…

位運算,雙指針,二分,排序算法

文章目錄 位運算二進制中1的個數題解代碼我們需要0題解代碼 排序模版排序1題解代碼模版排序2題解代碼模版排序3題解代碼 雙指針最長連續不重復子序列題解代碼 二分查找題解代碼 位運算 1. bitset< 16 >將十進制數轉為16位的二進制數 int x 25; cout << bitset<…

一周學會Flask3 Python Web開發-redirect重定向

鋒哥原創的Flask3 Python Web開發 Flask3視頻教程&#xff1a; 2025版 Flask3 Python web開發 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 前面我們學過渲染到模板頁面&#xff0c;這個其實是一種內部的轉發&#xff0c;瀏覽器地址欄地址沒有變化。如果我們想重定向…

圖片粘貼上傳實現

圖片上傳 html demo 直接粘貼本地運行查看效果即可&#xff0c;有看不懂的直接喂給 deepseek 會解釋的很清晰 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"…

RedisTemplate存儲含有特殊字符解決

ERROR信息: 案發時間: 2025-02-18 01:01 案發現場: UserServiceImpl.java 嫌疑人: stringRedisTemplate.opsForValue().set(SystemConstants.LOGIN_CODE_PREFIX phone, code, Duration.ofMinutes(3L)); // 3分鐘過期作案動機: stringRedisTemplate繼承了Redistemplate 使用的…

Python正則表達式學習

Python正則表達式全攻略 一、正則表達式基礎 1. 什么是正則表達式&#xff1f; 用于描述字符串匹配規則的表達式廣泛應用于文本處理、表單驗證、數據清洗等領域 2. Python中的re模塊 import re3. 基礎語法 字符說明示例.匹配任意字符(除換行)a.c → abc\d數字 [0-9]\d\d …

20250218 隨筆 垂直分庫分表(Vertical Sharding) 和 水平分庫分表(Horizontal Sharding)

垂直分庫分表&#xff08;Vertical Sharding&#xff09; 和 水平分庫分表&#xff08;Horizontal Sharding&#xff09; 是數據庫拆分的兩種策略。它們在大規模數據庫優化、分布式架構設計中至關重要&#xff0c;主要用于 降低單庫壓力、提高查詢效率、支持高并發。 1. 垂直分…

notepad++右鍵菜單不見了

卸載時沒點擊完成&#xff0c;又重新安裝了一個&#xff0c;最終導致了一些bug&#xff0c;導致右鍵沒有notepad菜單。 解決方式&#xff1a; 新建一個register.reg文件&#xff0c;加入以下代碼&#xff0c;然后雙擊執行即可 代碼說明&#xff1a;Open with Notepad 是右…

重定向與文件緩沖機制

目錄 一、重定向的原理與實踐 1. 輸出重定向&#xff1a;讓數據流向新目的地 2. 追加重定向&#xff1a;在文件末尾追加數據 3. 輸入重定向&#xff1a;從指定文件讀取數據 4. 標準輸出流與標準錯誤流的區別 5. 使用 dup2 實現重定向 二、FILE 結構體的奧秘 1. FILE 中的…