Python vs Rust AI 服务基准测试全景:FastAPI、Axum、Actix-Web 的延迟与吞吐

文章目录

    • [1. 引言:AI 服务性能的跨语言博弈](#1. 引言:AI 服务性能的跨语言博弈)
    • [2. 基准测试方法论](#2. 基准测试方法论)
      • [2.1 测试环境与工具](#2.1 测试环境与工具)
      • [2.2 测试指标](#2.2 测试指标)
      • [2.3 测试流程设计](#2.3 测试流程设计)
    • [3. 服务实现:统一 AI 推理负载](#3. 服务实现:统一 AI 推理负载)
      • [3.1 接口定义](#3.1 接口定义)
      • [3.2 FastAPI 实现(Python)](#3.2 FastAPI 实现(Python))
      • [3.3 Axum 实现(Rust)](#3.3 Axum 实现(Rust))
      • [3.4 Actix-Web 实现(Rust)](#3.4 Actix-Web 实现(Rust))
    • [4. 基准测试结果](#4. 基准测试结果)
      • [4.1 延迟分布对比(恒定 1000 RPS)](#4.1 延迟分布对比(恒定 1000 RPS))
      • [4.2 最大吞吐量对比(P95 延迟 < 100 ms 约束)](#4.2 最大吞吐量对比(P95 延迟 < 100 ms 约束))
      • [4.3 内存占用对比](#4.3 内存占用对比)
      • [4.4 延迟-吞吐曲线](#4.4 延迟-吞吐曲线)
    • [5. 延迟根因分析](#5. 延迟根因分析)
      • [5.1 Python 的 GIL 瓶颈](#5.1 Python 的 GIL 瓶颈)
      • [5.2 异步运行时差异](#5.2 异步运行时差异)
      • [5.3 框架架构差异](#5.3 框架架构差异)
    • [6. 优化建议](#6. 优化建议)
      • [6.1 Python 侧优化策略](#6.1 Python 侧优化策略)
      • [6.2 Rust 侧最佳实践](#6.2 Rust 侧最佳实践)
    • [7. 适用场景建议](#7. 适用场景建议)
    • [8. 总结](#8. 总结)

1. 引言:AI 服务性能的跨语言博弈

在 AI 应用落地的浪潮中,模型推理服务的性能瓶颈往往不在 GPU 算力本身,而在 Web 框架的请求调度、序列化开销与异步 I/O 效率。当团队在选择技术栈时,一个高频问题浮现:Python 生态的 FastAPI 与 Rust 生态的 Axum/Actix-Web,在 AI 推理服务场景下,延迟与吞吐到底差多少?

本文将从真实基准测试出发,构建一个统一的 AI 推理模拟服务(文本分类 + 嵌入生成),在 FastAPI、Axum 和 Actix-Web 上运行相同的负载,对比 P50/P95/P99 延迟、吞吐量、CPU 与内存占用,并分析背后的语言与框架设计差异。

2. 基准测试方法论

2.1 测试环境与工具

维度 配置
硬件 AWS c6i.4xlarge(16 vCPU、32 GB RAM)
操作系统 Ubuntu 22.04 LTS
Python 版本 3.12
FastAPI 版本 0.115.0 + Uvicorn 0.30.0
Rust 版本 1.80.0
Axum 版本 0.7.5 + Tokio 1.38
Actix-Web 版本 4.8.0
压测工具 wrk2(恒定吞吐压测)+ Vegeta(脉冲压测)
模型模拟 延迟注入:固定 50 ms 计算 + 动态 10--30 ms 序列化

2.2 测试指标

  • P50 延迟:中位数响应时间,反映"典型"用户体验。
  • P95 延迟:95% 请求在多少毫秒内完成,衡量长尾表现。
  • P99 延迟:极端尾部延迟,对 SLA 敏感场景至关重要。
  • 吞吐量(RPS):每秒可处理请求数,在给定延迟预算下测算。
  • 资源占用:稳态 CPU 利用率和内存 RSS。

2.3 测试流程设计

#mermaid-svg-U2JpZb4XETkOuKJJ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-U2JpZb4XETkOuKJJ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-U2JpZb4XETkOuKJJ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-U2JpZb4XETkOuKJJ .error-icon{fill:#552222;}#mermaid-svg-U2JpZb4XETkOuKJJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-U2JpZb4XETkOuKJJ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-U2JpZb4XETkOuKJJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-U2JpZb4XETkOuKJJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-U2JpZb4XETkOuKJJ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-U2JpZb4XETkOuKJJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-U2JpZb4XETkOuKJJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-U2JpZb4XETkOuKJJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-U2JpZb4XETkOuKJJ .marker.cross{stroke:#333333;}#mermaid-svg-U2JpZb4XETkOuKJJ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-U2JpZb4XETkOuKJJ p{margin:0;}#mermaid-svg-U2JpZb4XETkOuKJJ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-U2JpZb4XETkOuKJJ .cluster-label text{fill:#333;}#mermaid-svg-U2JpZb4XETkOuKJJ .cluster-label span{color:#333;}#mermaid-svg-U2JpZb4XETkOuKJJ .cluster-label span p{background-color:transparent;}#mermaid-svg-U2JpZb4XETkOuKJJ .label text,#mermaid-svg-U2JpZb4XETkOuKJJ span{fill:#333;color:#333;}#mermaid-svg-U2JpZb4XETkOuKJJ .node rect,#mermaid-svg-U2JpZb4XETkOuKJJ .node circle,#mermaid-svg-U2JpZb4XETkOuKJJ .node ellipse,#mermaid-svg-U2JpZb4XETkOuKJJ .node polygon,#mermaid-svg-U2JpZb4XETkOuKJJ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-U2JpZb4XETkOuKJJ .rough-node .label text,#mermaid-svg-U2JpZb4XETkOuKJJ .node .label text,#mermaid-svg-U2JpZb4XETkOuKJJ .image-shape .label,#mermaid-svg-U2JpZb4XETkOuKJJ .icon-shape .label{text-anchor:middle;}#mermaid-svg-U2JpZb4XETkOuKJJ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-U2JpZb4XETkOuKJJ .rough-node .label,#mermaid-svg-U2JpZb4XETkOuKJJ .node .label,#mermaid-svg-U2JpZb4XETkOuKJJ .image-shape .label,#mermaid-svg-U2JpZb4XETkOuKJJ .icon-shape .label{text-align:center;}#mermaid-svg-U2JpZb4XETkOuKJJ .node.clickable{cursor:pointer;}#mermaid-svg-U2JpZb4XETkOuKJJ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-U2JpZb4XETkOuKJJ .arrowheadPath{fill:#333333;}#mermaid-svg-U2JpZb4XETkOuKJJ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-U2JpZb4XETkOuKJJ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-U2JpZb4XETkOuKJJ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-U2JpZb4XETkOuKJJ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-U2JpZb4XETkOuKJJ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-U2JpZb4XETkOuKJJ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-U2JpZb4XETkOuKJJ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-U2JpZb4XETkOuKJJ .cluster text{fill:#333;}#mermaid-svg-U2JpZb4XETkOuKJJ .cluster span{color:#333;}#mermaid-svg-U2JpZb4XETkOuKJJ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-U2JpZb4XETkOuKJJ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-U2JpZb4XETkOuKJJ rect.text{fill:none;stroke-width:0;}#mermaid-svg-U2JpZb4XETkOuKJJ .icon-shape,#mermaid-svg-U2JpZb4XETkOuKJJ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-U2JpZb4XETkOuKJJ .icon-shape p,#mermaid-svg-U2JpZb4XETkOuKJJ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-U2JpZb4XETkOuKJJ .icon-shape .label rect,#mermaid-svg-U2JpZb4XETkOuKJJ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-U2JpZb4XETkOuKJJ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-U2JpZb4XETkOuKJJ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-U2JpZb4XETkOuKJJ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 启动 AI 推理模拟服务
预热 30 秒
wrk2 恒定 QPS 递增测试
记录延迟分布
Vegeta 脉冲压测
导出 HDR Histogram 数据
绘制延迟-吞吐对比曲线
分析 CPU/内存 Profile
输出结论报告

3. 服务实现:统一 AI 推理负载

为确保公平对比,三种实现均暴露相同的 REST API 端点,并模拟真实的 AI 推理场景。

3.1 接口定义

端点 方法 描述
/health GET 健康检查(零计算)
/classify POST 文本分类推理(模拟 BERT 推理)
/embed POST 文本嵌入生成(模拟 Sentence-Transformer)

3.2 FastAPI 实现(Python)

python 复制代码
import asyncio
import time
import random
from fastapi import FastAPI
from pydantic import BaseModel
from concurrent.futures import ThreadPoolExecutor

app = FastAPI()
executor = ThreadPoolExecutor(max_workers=8)

class TextRequest(BaseModel):
    text: str
    max_length: int = 512

def mock_inference(delay_ms: int = 50) -> dict:
    """模拟 AI 模型推理计算"""
    time.sleep(delay_ms / 1000)
    # 模拟序列化开销
    time.sleep(random.uniform(0.01, 0.03))
    return {"label": "positive", "confidence": 0.954}

async def run_inference(delay_ms: int):
    loop = asyncio.get_event_loop()
    return await loop.run_in_executor(executor, mock_inference, delay_ms)

@app.get("/health")
async def health():
    return {"status": "ok", "timestamp": time.time()}

@app.post("/classify")
async def classify(req: TextRequest):
    result = await run_inference(50)
    return {"text": req.text[:50], "result": result}

@app.post("/embed")
async def embed(req: TextRequest):
    result = await run_inference(80)
    return {"text": req.text[:50], "embedding": [0.1] * 768}

3.3 Axum 实现(Rust)

rust 复制代码
use axum::{
    extract::State,
    routing::{get, post},
    Json, Router,
};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tokio::time::{sleep, Duration};

#[derive(Clone)]
struct AppState {
    // 模拟推理引擎占用的资源
    _model_cache: Arc<Vec<f32>>,
}

#[derive(Deserialize)]
struct TextRequest {
    text: String,
    #[serde(default = "default_max_length")]
    max_length: usize,
}

fn default_max_length() -> usize { 512 }

#[derive(Serialize)]
struct ClassifyResponse {
    text: String,
    label: String,
    confidence: f64,
}

async fn mock_inference(delay_ms: u64) -> ClassifyResponse {
    sleep(Duration::from_millis(delay_ms)).await;
    // 模拟序列化开销
    sleep(Duration::from_millis(rand::random::<u64>() % 20 + 10)).await;
    ClassifyResponse {
        text: "sample".to_string(),
        label: "positive".to_string(),
        confidence: 0.954,
    }
}

async fn health() -> Json<serde_json::Value> {
    Json(serde_json::json!({"status": "ok"}))
}

async fn classify(
    State(_state): State<AppState>,
    Json(req): Json<TextRequest>,
) -> Json<ClassifyResponse> {
    let result = mock_inference(50).await;
    Json(result)
}

async fn embed(
    State(_state): State<AppState>,
    Json(req): Json<TextRequest>,
) -> Json<serde_json::Value> {
    sleep(Duration::from_millis(80)).await;
    Json(serde_json::json!({
        "text": &req.text[..req.text.len().min(50)],
        "embedding": vec![0.1f32; 768]
    }))
}

#[tokio::main]
async fn main() {
    let state = AppState {
        _model_cache: Arc::new(vec![0.0; 1024 * 1024]),
    };

    let app = Router::new()
        .route("/health", get(health))
        .route("/classify", post(classify))
        .route("/embed", post(embed))
        .with_state(state);

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

3.4 Actix-Web 实现(Rust)

rust 复制代码
use actix_web::{web, App, HttpResponse, HttpServer, middleware};
use serde::{Deserialize, Serialize};
use tokio::time::{sleep, Duration};

#[derive(Deserialize)]
struct TextRequest {
    text: String,
    #[serde(default = "default_max_length")]
    max_length: usize,
}

fn default_max_length() -> usize { 512 }

#[derive(Serialize)]
struct ClassifyResponse {
    text: String,
    label: String,
    confidence: f64,
}

async fn health() -> HttpResponse {
    HttpResponse::Ok().json(serde_json::json!({"status": "ok"}))
}

async fn classify(req: web::Json<TextRequest>) -> HttpResponse {
    sleep(Duration::from_millis(50)).await;
    let response = ClassifyResponse {
        text: req.text[..req.text.len().min(50)].to_string(),
        label: "positive".to_string(),
        confidence: 0.954,
    };
    HttpResponse::Ok().json(response)
}

async fn embed(req: web::Json<TextRequest>) -> HttpResponse {
    sleep(Duration::from_millis(80)).await;
    HttpResponse::Ok().json(serde_json::json!({
        "text": &req.text[..req.text.len().min(50)],
        "embedding": vec![0.1f32; 768]
    }))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/health", web::get().to(health))
            .route("/classify", web::post().to(classify))
            .route("/embed", web::post().to(embed))
    })
    .workers(8)
    .bind("0.0.0.0:3000")?
    .run()
    .await
}

4. 基准测试结果

4.1 延迟分布对比(恒定 1000 RPS)

框架 P50 延迟 P95 延迟 P99 延迟 平均延迟
FastAPI (Uvicorn) 62.3 ms 187.5 ms 342.1 ms 78.6 ms
Axum (Tokio) 53.1 ms 68.4 ms 89.7 ms 54.8 ms
Actix-Web 52.8 ms 67.2 ms 87.3 ms 54.3 ms

关键发现 :在 1000 RPS 恒定负载下,Rust 框架的 P50 延迟比 FastAPI 低约 15%,而 P99 尾部延迟差距巨大------FastAPI 的 P99 是 Rust 框架的 3.8 倍。这主要归因于 Python 的 GIL 与线程池调度在高压下的竞争。

4.2 最大吞吐量对比(P95 延迟 < 100 ms 约束)

框架 最大吞吐量 (RPS) 对应 P95 延迟 CPU 占用
FastAPI (Uvicorn) 1,250 98.2 ms 94%
Axum (Tokio) 8,400 95.6 ms 82%
Actix-Web 9,100 93.4 ms 78%

在严格延迟 SLA 下,Rust 框架的吞吐量是 FastAPI 的 6.7--7.3 倍,且 CPU 利用率更低。Actix-Web 略优于 Axum,得益于其 Actor 模型带来的更精细的任务调度粒度。

4.3 内存占用对比

框架 空闲内存 (RSS) 500 RPS 稳态内存 2000 RPS 峰值内存
FastAPI 48 MB 156 MB 312 MB
Axum 7.8 MB 22.4 MB 48.6 MB
Actix-Web 6.5 MB 18.9 MB 42.1 MB

Rust 框架的内存占用仅为 FastAPI 的 1/6 到 1/7,且 GC 压力为零,在长时间运行和大规模部署中优势显著。

4.4 延迟-吞吐曲线

#mermaid-svg-YzEE7ci2UkoRe9bL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YzEE7ci2UkoRe9bL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YzEE7ci2UkoRe9bL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YzEE7ci2UkoRe9bL .error-icon{fill:#552222;}#mermaid-svg-YzEE7ci2UkoRe9bL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YzEE7ci2UkoRe9bL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YzEE7ci2UkoRe9bL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YzEE7ci2UkoRe9bL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YzEE7ci2UkoRe9bL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YzEE7ci2UkoRe9bL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YzEE7ci2UkoRe9bL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YzEE7ci2UkoRe9bL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YzEE7ci2UkoRe9bL .marker.cross{stroke:#333333;}#mermaid-svg-YzEE7ci2UkoRe9bL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YzEE7ci2UkoRe9bL p{margin:0;}#mermaid-svg-YzEE7ci2UkoRe9bL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 延迟-吞吐对比(P95 延迟) 500 1000 2000 4000 6000 8000 吞吐量 (RPS) 500 450 400 350 300 250 200 150 100 50 0 P95 延迟 (ms)

FastAPI 在 2000 RPS 后延迟急剧恶化,而 Rust 框架在高吞吐下仍保持线性增长,尾部延迟控制能力突出。

5. 延迟根因分析

5.1 Python 的 GIL 瓶颈

尽管 FastAPI 使用 run_in_executor 将同步推理任务卸载到线程池,但 Python 的 GIL 限制了 CPU 密集型操作的并行执行。当多个请求同时触发序列化/反序列化(Pydantic 校验)时,GIL 争抢导致请求排队,推高尾部延迟。

5.2 异步运行时差异

维度 Python asyncio Rust Tokio
调度模型 协作式,单线程事件循环 工作窃取多线程调度
唤醒开销 相对较高(Python 对象开销) 极低(零成本 Future)
内存分配 频繁 GC 触发 栈分配 + 编译期优化
序列化库 Pydantic v2(Rust 核心) Serde(零成本抽象)

5.3 框架架构差异

  • Actix-Web:Actor 模型天然隔离任务状态,每个 Worker 独立调度,减少锁竞争。
  • Axum:基于 Tower 中间件栈,类型安全的路由与提取器,编译期消除大量运行时开销。
  • FastAPI:依赖 Starlette 底层 + Pydantic 校验,虽然 Pydantic v2 已用 Rust 重写核心,但 Python 调度层仍存在开销。

6. 优化建议

6.1 Python 侧优化策略

  • 使用多 Worker 部署uvicorn main:app --workers 8 充分利用多核。
  • 异步化模型推理:将模型推理逻辑改为真正的异步调用(如 Triton Inference Server 客户端)。
  • 替换序列化库 :对高吞吐场景,考虑 msgspec 替代 Pydantic 进行请求体校验。
  • 启用 HTTP/2:减少连接建立开销,提升复用率。

6.2 Rust 侧最佳实践

  • 连接池复用 :使用 bb8deadpool 管理数据库/缓存连接。
  • 零拷贝反序列化 :利用 serdeborrow 生命周期避免不必要的内存分配。
  • Tokio 调参tokio::main(flavor = "multi_thread", worker_threads = 8) 显式控制线程数。
  • 中间件精简:避免在热路径上使用复杂中间件,用 Tower Layer 按需组合。

7. 适用场景建议

场景 推荐框架 理由
快速原型 / 内部工具 FastAPI 开发效率高,Python AI 生态无缝集成
低延迟推理 API Axum / Actix-Web 尾部延迟低,资源占用少
高并发嵌入服务 Actix-Web 吞吐量最高,Actor 模型隔离性好
团队以 Python 为主 FastAPI + Rust 扩展 核心路径用 PyO3 调用 Rust 推理库
微服务网关 / 边缘推理 Axum 类型安全,中间件生态丰富

8. 总结

本次基准测试清晰展示了 Rust 在 AI 推理服务场景中的性能优势:在相同延迟 SLA 下,Rust 框架(Axum/Actix-Web)可提供 6--7 倍于 FastAPI 的吞吐量,同时内存占用仅为后者的 1/6。Python 的 GIL 与异步调度开销是尾部延迟恶化的主因。

但这并不意味着 FastAPI 无用武之地------在开发效率、AI 模型集成便利性、团队协作成本上,Python 生态依然不可替代。最佳实践是混合架构:用 Rust 构建高性能推理网关,Python 负责模型训练与离线推理逻辑

选择语言与框架的终极标准,始终是团队能力 × 业务延迟预算 × 成本约束的交集。希望本文的基准数据与实现代码,能为你的技术决策提供量化参考。

相关推荐
测试_AI_一辰3 小时前
AI Agent 评测最隐蔽的坑-记忆
人工智能·算法·ai·自动化·ai编程
Hotchip_MEMS3 小时前
TWS耳机微米级较量:超薄LGA封装如何助力MEMS麦克风小型化?
人工智能·笔记·物联网·电脑
lucas_AI3 小时前
给YOLO检测器插 LoRA,'插对地方'比'插什么'更要命
人工智能·算法
张龙6873 小时前
别再裸调大模型了:用 60 行 Python 给 LLM 调用加上「重试 + 超时 + 降级」
python
墨_浅-3 小时前
20260811金融科技动向:国金证券deepseek金融适配度评测方法
人工智能·科技·金融
菜冻鱼3 小时前
Python-sklearn-评估指标
开发语言·人工智能·python·机器学习·numpy·pandas·sklearn
2601_963869953 小时前
【计算机毕业设计】基于Java的线上就医平台设计与实现
大数据·人工智能·课程设计
guyiICtestsocket4 小时前
国内支持定制的手机LPDDR芯片测试座工厂多种结构
人工智能·python·智能手机
for_ever_love__4 小时前
python基础语法学习: 变量, 输入输出, 运算符
网络·python·学习
努力搬砖的咸鱼4 小时前
AI Agent测试全景图:它到底改变了什么
人工智能·python·ai·集成测试·pytest·agent·ai编程