news 2026/9/12 18:35:18

Windows部署vLLM实战:WSL2+Docker运行Qwen3-8B-FP8全攻略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Windows部署vLLM实战:WSL2+Docker运行Qwen3-8B-FP8全攻略

1. 写在前面:Windows 跑 vLLM,为什么这么折腾

说个可能让很多人意外的事实:vLLM 官方压根没有提供 Windows 原生版本。我去年第一次在 Windows 上尝试pip install vllm,折腾了一整天,最后卡在编译环节报了一堆 MSVC 和 CUDA 相关的错。后来我才明白,vLLM 依赖的很多底层组件(比如 NCCL、CUDA Graph、页式注意力内核)在 Windows 环境下支持都不完整,硬怼源码编译非常痛苦。

但这不等于 Windows 用户就和 vLLM 无缘了。现在主流的做法就是两条路:用 WSL2(Windows Subsystem for Linux 第二版)里的 Ubuntu 环境跑,或者用 Docker Desktop 的 WSL2 后端跑容器化的 vLLM。两条路我都实测过,今天这篇就围绕Qwen3-8B-FP8这个模型,完整记录从零开始的部署过程和踩坑实录。

这篇内容适合谁?如果你手里有一张 NVIDIA 显卡(显存最好在 12GB 以上),想在 Windows 上本地跑一个大模型来做应用开发、接口测试或者学习 vLLM 的服务化部署,那这篇就是为你准备的。我不打算只贴命令,还会把每一步为什么要这么做的逻辑讲清楚——知道了原理,出问题你才知道往哪个方向排查。

2. 整体部署思路:为什么必须走 WSL2 这条路

2.1 先弄清楚 vLLM 和 Windows 之间的兼容性边界

vLLM 从诞生之初就是面向 Linux 服务器环境设计的。它的核心是 PagedAttention 和一系列高度优化的 CUDA Kernel,这些 Kernel 需要和 PyTorch、CUDA Toolkit、NCCL 通信库深度绑定。在 Linux 上,这套组合拳打得很顺;但到了 Windows 上,你就得面对几个绕不开的问题:

一是NCCL 没有 Windows 官方版本。NCCL 是 NVIDIA 的集合通信库,vLLM 做张量并行(Tensor Parallelism)和流水线并行(Pipeline Parallelism)时都要靠它。没有 NCCL,多卡场景完全没法玩,单卡模式下虽然某些版本可以绕过,但报错频率会明显变高。

二是编译链路不稳定。vLLM 的部分算子需要即时编译(JIT),Windows 上 MSVC 和 CUDA 环境的兼容性问题会导致莫名其妙的编译错误。我见过最离谱的一个错误是链接器找不到符号,重装三遍 CUDA 都解决不了,最后换到 WSL2 直接就好了。

三是官方根本没有 Win 支持计划。你去 vLLM 的 GitHub Issues 里搜 Windows,会发现相关 issue 常年挂着,核心维护者的态度也很明确:请用 WSL2 或 Docker。所以,除非你有特别强的理由必须原生跑 Windows,否则别在这上面浪费时间。

2.2 三条可行路线的优缺点对比

实际部署时有这么几种选择,我把它们的优缺点整理成了一张表:

方案优点缺点适合人群
WSL2 内裸装 Python 环境环境可控性最强,调试方便,资源开销小需要自己搞定 CUDA、PyTorch、vLLM 的版本匹配喜欢手动折腾、想深入学习原理的开发者
Docker Desktop + WSL2 后端隔离性好,镜像即拿即用,不会污染宿主机镜像很大,文件系统 IO 在跨磁盘时会有性能损耗想快速跑通、不想折腾环境依赖的工程师
Windows 原生源码编译理论上可行编译坑多,很多算子无法启用,性能有损耗不推荐,除非你有特殊需求

我自己最常用的组合是WSL2 Ubuntu + Docker。理由很简单:vLLM 官方提供了现成的 Docker 镜像,里面 CUDA、PyTorch、NCCL 都是匹配好的,不需要自己纠结版本。而且在 WSL2 里跑 Docker,GPU 透传是开箱即用的,比在纯 Windows 下做 GPU 虚拟化要省心得多。

这里要多说一句:WSL2 其实是一个轻量级虚拟机,但它对 GPU 的透传做得很完善。你在 Windows 宿主上装的 NVIDIA 驱动,WSL2 里面直接就能用,不需要额外装驱动。这个特性是部署 vLLM 的关键前提。

2.3 为什么选 Qwen3-8B-FP8 作为目标模型

先说结论:Qwen3-8B-FP8 是目前在消费级显卡上做本地部署性价比极高的选择。原因有三点。

第一,8B 参数量是个甜点区间。这个量级的模型既保留了较强的通用理解和生成能力,又不会像 70B 那样对显存提出超出常规硬件的要求。

第二,FP8 量化大幅降低了显存门槛。FP8 格式下每个参数只占 1 字节(相比之下 FP16 占 2 字节、FP32 占 4 字节),8B 模型的权重体积大约是 8GB 左右。也就是说,一张 12GB 显存的显卡就基本能装下整个模型权重,剩下的空间留给 KV Cache 和激活值。实际推理时 12GB 会非常紧张,但 16GB 或 24GB 就很从容了。

第三,Qwen3 系列原生支持 FP8 量化推理,不是那种需要额外转换的旁路操作,官方直接发布了 FP8 权重版本,拉下来就能用。这一点对新手特别友好,不需要自己跑量化流程。

3. 环境准备与关键前置配置

3.1 Windows 侧需要提前确认的三件事

在动手之前,请先花五分钟确认三个前置条件,否则后续会反复返工。

第一,显卡驱动必须是最新版本。这不是玄学。WSL2 里访问 GPU 依赖宿主机驱动提供 WDDM 和 CUDA 支持,老版本驱动可能不支持最新的 CUDA 12.x 特性。我第一次部署时用的驱动是半年多前的,结果 vLLM 报了个很奇怪的内核加载错误。更新驱动后所有报错全部消失。

注意:这里的"更新驱动"指的是 Windows 宿主机的 NVIDIA 驱动,不是 WSL 内部的。WSL2 内部不需要也不能单独安装 NVIDIA 驱动。

第二,确认你的 Windows 版本支持 WSL2。Windows 10 版本 21H2 及以上、Windows 11 都支持。如果你还在用老版本 Windows 10,建议先升级系统,否则 WSL2 装不上或者装上了也不稳定。

第三,看准显存容量和架构。vLLM 对显卡的架构有最低要求:官方支持的架构是 Volta、Ampere、Ada Lovelace、Hopper 等,古老一些的 Pascal 架构(GTX 10 系)是不被支持的。你可以用 NVIDIA-SMI 或者在 Windows 的任务管理器中查看 GPU 型号。我实测下来,RTX 3060 12GB、RTX 4060 Laptop 8GB、RTX 3090 24GB 都能跑通,只是 8GB 显存的话需要把--max-model-len调得特别低。

3.2 WSL2 环境安装与 Docker Desktop 配置

先打开 PowerShell(管理员模式),执行下面的命令安装 WSL2:

wsl --install

这条命令默认会安装 Ubuntu 最新 LTS 版本。装好后重启系统,打开 Ubuntu 终端,先做两件事:更新软件源、设置默认用户密码。

sudo apt update && sudo apt upgrade -y

然后安装 Docker Desktop。这里有个重点:Docker Desktop 需要勾选使用 WSL2 后端。安装完成后,在 Settings 里的 Resources 选项卡里,确保你的 Ubuntu 发行版出现在"Enable integration with my default WSL distro"列表中。

安装完成后你不需要在 Ubuntu 里再装 Docker命令行工具,Docker Desktop 会自动处理好 WSL2 里的 Docker 命令映射。实测下来,直接在 Ubuntu 终端里执行docker --version就能看到版本信息。

关于 GPU 支持,由于 Docker Desktop 会通过 WSL2 透传 GPU,所以容器里不需要安装驱动。但需要额外做一件事:确认宿主机驱动支持 CUDA on WSL。可以在 Ubuntu 终端执行:

nvidia-smi

如果能看到 GPU 信息,说明 WSL2 的 GPU 透传已经就绪。这一步经常有人漏掉,直接在 Docker 里跑 vLLM 时才发现 GPU 不可用,白白浪费一晚上。

3.3 显存规划:Qwen3-8B-FP8 到底需要多大显存

很多新手容易犯一个错误:只看模型文件的大小,以为 8GB 权重 + 2GB 余量就够了。实际上 vLLM 运行时的显存占用包括好几个部分:

  • 模型权重:FP8 格式下约 8GB
  • KV Cache:由--max-model-len--gpu-memory-utilization两个参数共同决定。默认情况下,vLLM 会占用显卡剩余可用显存的一部分来分配 KV Cache
  • CUDA Context 和激活值:这部分最容易忽略,实际占用大约 1GB 到 2GB
  • 推理计算时的临时缓冲区:视并发请求量浮动

以 RTX 3090 24GB 为例,跑 Qwen3-8B-FP8 时,模型权重 8GB,CUDA 开销 2GB,留给 KV Cache 的大约 14GB。在默认配置下,max-model-len可以开到 32768 甚至 65536,非常从容。

如果是 RTX 3060 12GB,那就紧张不少。权重 8GB + CUDA 2GB 只剩 2GB 给 KV Cache,这种情况下max-model-len只能开到 4096 或者 8192,并且--gpu-memory-utilization建议拉到 0.95,尽可能压缩其他开销。

重要提示:如果启动时报CUDA out of memory,不要盲目加显存或换卡。优先检查--max-model-len是否过大,这是最常见的显存爆炸原因。

4. 实操部署:Docker 方案完整步骤拆解

4.1 拉取镜像与首次启动检查

一切准备就绪后,接下来就是正式的部署环节。我推荐用 Docker 方式,因为官方镜像把所有依赖都封好了,你不需要经历 pip 安装时各种版本冲突的折磨。

打开 Ubuntu 终端,执行:

docker pull vllm/vllm-openai:latest

这个镜像包含 vLLM 的 OpenAI 兼容 API 服务端。镜像体积大概 6GB 左右,下载时间取决于你的网速。如果你处在网络不稳定的环境,建议配置 Docker 的镜像加速器。

镜像拉取完成后,先不要急着跑模型。执行下面这个命令验证 GPU 是否能在容器里正常访问:

docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi

如果能看到 GPU 信息,说明 Docker 的 GPU 透传链路是通的。这一步验证非常重要,我遇到过好几次 Docker Desktop 更新后 GPU 集成失效的情况,都是靠这行命令提前发现了问题。

4.2 启动 Qwen3-8B-FP8 服务:命令与参数详解

验证通过后,直接启动 vLLM 服务。完整的命令如下:

docker run --gpus all \ -v /mnt/e/llm-models:/models \ -p 8000:8000 \ --ipc=host \ --shm-size=16g \ vllm/vllm-openai:latest \ --model /models/Qwen3-8B-FP8 \ --served-model-name qwen3-8b \ --max-model-len 8192 \ --gpu-memory-utilization 0.9 \ --enforce-eager

我先逐个解释一下这个命令里每个参数的作用,因为很多人只是照抄命令,一旦想改点什么就懵了。

-v /mnt/e/llm-models:/models:把宿主机存放模型的目录挂载到容器里的/models路径。我把模型预先下载到了 Windows 的 E 盘,在 WSL2 里对应的路径就是/mnt/e/llm-models。这个路径规则是 WSL2 自动挂载 Windows 磁盘的约定,别忘了。

--ipc=host--shm-size=16g:这两个都是共享内存相关的配置。vLLM 的多卡通信和某些张量操作依赖共享内存,默认的 64MB 完全不够用,不设置的话很容易在运行时报错。这个是从 vLLM 官方文档里继承来的最佳实践,直接抄就行。

--served-model-name qwen3-8b:给模型起一个对外暴露的名字。因为模型目录名可能与模型真实名称不一致,这个参数让客户端可以用统一的名字来请求。

--max-model-len 8192:限制模型最大的上下文长度。如果你的显存比较大(比如 24GB),可以开到 32768 或更高;如果显存只有 12GB,建议先保持 8192,后续根据显存占用情况再调整。

--gpu-memory-utilization 0.9:告诉 vLLM 最多可以使用显卡 90% 的显存。留出 10% 给系统和其他进程,避免显存完全打满后引发异常。如果你的机器只跑 vLLM 这一个服务,可以调到 0.95。

--enforce-eager:这一项要重点说明。vLLM 默认会使用 CUDA Graph 来优化推理性能,但这个优化在 WSL2 环境下偶尔会触发兼容性问题。--enforce-eager会强制禁用 CUDA Graph,虽然速度稍有下降,但换来了稳定性。我在 WSL2 上实测时第一次没加这个参数,启动直接卡死了。如果动作完成后想追求极限性能,可以在移除该参数的情况下测试是否稳定。

4.3 模型文件的获取与组织方式

启动命令里引用了/models/Qwen3-8B-FP8路径,这意味着你必须先把模型文件准备好。获取 Qwen3-8B-FP8 权重有两种方式。

方式一:直接用huggingface-cli下载。在 WSL2 中执行:

pip install -U huggingface_hub huggingface-cli download Qwen/Qwen3-8B-FP8 --local-dir /mnt/e/llm-models/Qwen3-8B-FP8

方式二:使用 modelscope(如果访问 HuggingFace 不稳定,在部分网络环境下切到国内源会更顺)。执行:

pip install modelscope modelscope download --model Qwen/Qwen3-8B-FP8 --local_dir /mnt/e/llm-models/Qwen3-8B-FP8

下载完成后,确认目录里至少包含这几个关键文件:config.jsonmodel.safetensors(或分片的model-00001-of-0000X.safetensors)、tokenizer.jsontokenizer_config.json

这里有个常见的坑:模型下载不完整会导致启动时静默失败。vLLM 启动时不会主动校验文件完整性,你可能会看到一些莫名其妙的错误信息。所以下载完成后,建议先在终端里查一下文件大小:

ls -lh /mnt/e/llm-models/Qwen3-8B-FP8

4.4 调用测试:从 OpenAI 兼容接口到 Python 客户端

服务启动成功后,命令行会输出类似INFO: Started server process ...INFO: Uvicorn running on http://0.0.0.0:8000的日志。这时候就可以测试了。

先做一次最直接的 curl 测试,确认服务正常响应:

curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen3-8b", "messages": [{"role": "user", "content": "你好,请用一句话介绍一下你自己"}], "max_tokens": 128 }'

如果一切正常,你会收到一个 JSON 响应,里面包含了模型生成的回复内容。这里有一个细节:请求体里的"model"字段必须和你启动服务时传入的--served-model-name保持一致,否则会报Model Not Found

接下来是 Python 客户端的标准测试方式。用openai库来调用 vLLM 提供的接口,这样后续接入其他应用时改动最小:

from openai import OpenAI client = OpenAI( base_url="http://localhost:8000/v1", api_key="EMPTY", ) chat_completion = client.chat.completions.create( model="qwen3-8b", messages=[ {"role": "system", "content": "你是一个乐于助人的助手。"}, {"role": "user", "content": "给我讲一个关于程序员的笑话"} ], temperature=0.7, max_tokens=256, ) print(chat_completion.choices[0].message.content)

到这里,你的 Windows 环境下就已经跑通了一个本地大模型推理服务,并且通过 OpenAI 兼容接口暴露出来了。这意味着你可以直接接入 LangChain、Dify、FastGPT 等框架,或者自研应用的 API 层,后续扩展非常自由。

5. 常见启动报错与排查技巧实录

这部分是全文最值的部分。我把自己在 WSL2 + Docker 部署 vLLM 时踩过的坑全部整理出来,按错误出现的频率排序。你照着这个清单排查,能省下至少一晚上的折腾时间。

5.1 GPU 不可见或CUDA error: no kernel image is available

现象:启动 vLLM 时,日志里出现类似CUDA error: no kernel image is available for execution on the device,或者 Python 报错说无法使用 CUDA。

排查思路:首先确认 WSL2 里的nvidia-smi是否正常显示 GPU。如果这一步正常,问题基本出在 Docker 层的 GPU 透传。大概率是 Docker Desktop 的 WSL2 集成没有完全开启,或者你运行的容器没有加--gpus all参数。

还有个容易被忽略的点:容器镜像里的 CUDA 版本和宿主机驱动的 CUDA 版本存在一个兼容性范围。WSL2 里的 CUDA 驱动其实是由宿主机控制,但驱动不能太老。简单粗暴的解法就是把 Windows 的 NVIDIA 驱动升级到最新版,然后重启 Docker Desktop。

如果你已经在 WSL2 终端执行过nvidia-smi且正常输出,但容器内还是报错,试试重启 Docker Desktop 的 WSL2 集成:

wsl --shutdown

然后重新打开 Ubuntu 终端和 Docker Desktop。这一招能解决大量"看起来配置没问题但就是不行"的诡异问题。

5.2 显存溢出(CUDA Out of Memory)

现象:启动命令执行到加载模型权重时,vLLM 报CUDA out of memory

排查思路:如果显卡是 12GB 显存,那--max-model-len 8192有可能会撑爆显存。因为 8192 上下文长度对应的 KV Cache 在 FP8 权重下依然可能占用 3GB 以上。

优先调整以下参数:

  • --max-model-len降到 4096
  • --gpu-memory-utilization从 0.9 降到 0.8(给进程留更多缓冲)
  • 移除--enforce-eager的心智负担,这个参数会关闭 CUDA Graph 优化,减少显存峰值,虽然略损失性能但值得保留

如果你用的是 24GB 显存显卡还遇到 OOM,那就要怀疑是不是有其他进程占用显存。在 Windows 侧打开任务管理器看 GPU 显存占用,或者直接在 WSL2 里执行:

nvidia-smi

查看显存分配情况。注意 WSL2 里看到的显存信息是宿主机显存的虚拟化视图,不代表容器实际占用。

5.3 启动卡住或无限等待

现象:执行docker run后,终端长时间没有输出,或者日志停在某个地方不动。

排查思路:最常见的两个原因。第一,模型加载本身比较慢,8B 模型从磁盘读取 8GB 权重需要时间,如果模型存放在 Windows NTFS 分区而通过/mnt/路径挂载到容器,跨文件系统读写的速度会比原生 Linux 文件系统慢得多。这时候不要心急,等一两分钟是正常的。

第二,--enforce-eager参数忘加导致 CUDA Graph 初始化阶段卡住。这个在 WSL2 环境里出现的概率非常高,建议默认加上。

如果等了五分钟以上还是没反应,这时候可以按Ctrl+C停掉容器,然后用docker logs查看之前的输出:

docker ps -a docker logs <container_id>

看日志末尾有没有报错信息,Error 关键词的上下文通常会告诉你问题出在哪个环节。

5.4 请求响应极慢或首次请求超时

现象:服务启动成功,但第一次发送请求时等待很久,或者 curl 命令直接超时。

排查思路:vLLM 在收到第一个请求时会进行额外的初始化,包括 CUDA Kernel 预热、KV Cache 预分配等,所以首次请求延迟偏高是正常的。如果后续请求恢复正常,就不用管。如果每次都慢,检查是不是没加--enforce-eager而触发了某些不兼容的优化路径。

此外,如果你的模型文件放在机械硬盘上,首次读取权重会非常慢,导致加载阶段特别漫长。建议把模型文件放在 SSD 上。

5.5 常见问题速查表

问题常见原因解决办法
nvidia-smi 在 WSL2 中不可用宿主机驱动太旧或 WSL2 未重启升级 NVIDIA 驱动,执行wsl --shutdown后重开
容器内 GPU 不可见Docker Desktop 未集成 WSL2Settings 里开启 WSL2 后端,并在 Resources 中勾选发行版
启动时报 CUDA 版本错误镜像 CUDA 与驱动不匹配更新宿主机驱动,或换用 vLLM 官方推荐镜像
显存 OOMmax-model-len 或并发度过高降低 max-model-len,调低 gpu-memory-utilization
请求返回 404 Model Not Foundserved-model-name 与请求中的 model 不一致检查请求体里的 model 字段,确保和启动参数一致
生成速度很慢CUDA Graph 未启用或磁盘读取慢尝试去掉 enforce-eager(需保证稳定),模型文件放到 SSD

6. 性能调优与进阶使用建议

6.1 关键参数调节策略与显存测算

当你成功跑通默认配置后,下一步就是根据自己的硬件情况做调优。影响核心体验的参数有四个,按优先级排列:

--max-model-len是最直接影响显存分配的参数。我建议分级设置:12GB 显存用 4096 或 8192;16GB 显存用 16384;24GB 显存用 32768;如果再往上,就要确认实际业务是否真的需要这么长的上下文。上下文长度和 KV Cache 显存占用大致是线性关系,调大一倍上下文,KV Cache 也会翻倍。

--gpu-memory-utilization控制显存使用上限。这个参数决定了 vLLM 可以吃掉的显存比例,剩下的留给系统和避免 OOM。正常范围是 0.85 到 0.95,没有再往上调的必要,再高会显著增加 OOM 概率。

--max-num-seqs控制并发序列数量。默认值是 256,但对单用户个人部署来说太高了。如果你的并发请求量不大,建议改成 32 或 64,这样每个序列能分到更多显存资源,生成速度更稳定。

--enforce-eager是稳定性开关。保留它意味着禁用 CUDA Graph,性能有一定损失但换来稳定。我实测下来,Qwen3-8B-FP8 在 RTX 3090 上,开启 CUDA Graph 时生成速度大约是 80 tokens/s,关闭后降到大约 60 tokens/s。对于聊天应用来说,这个差距感知不明显,但如果做批量推理,建议测试开启 CUDA Graph 后的稳定性再决定。

6.2 从 OpenAI 兼容 API 到实际业务接入

vLLM 提供的是 OpenAI 兼容接口,这意味着你只需要修改base_urlapi_key,就可以把现有基于 OpenAI SDK 的应用接过来。

我在实际项目中通常这样接入 Dify 或 FastGPT 这类开源应用:

  • 在 Dify 的模型供应商设置中,选择 OpenAI API Compatible
  • API Base URL 填http://localhost:8000/v1
  • API Key 填任意值(vLLM 默认不校验 key,但字段需要存在)
  • Model Name 填启动时设置的qwen3-8b

这样只需要十几分钟就能把一个本地大模型接入到完整的 Agent 工作流里,而且不依赖任何外部 API 服务,数据安全性和成本可控性都更好。

6.3 WSL2 环境下的资源限制与性能瓶颈

最后补充一个很多人忽略的点:WSL2 自身有内存限制。默认情况下,WSL2 最多使用宿主机 50% 的内存,这个配置可以在%UserProfile%\.wslconfig文件里修改:

[wsl2] memory=16GB processors=8 swap=8GB

修改后执行wsl --shutdown再重新打开,配置才会生效。如果模型推理时需要吃大量内存(比如长上下文、批量请求),这个配置就很重要。我一开始用默认配置跑 vLLM,结果模型加载过程中 Ubuntu 直接被 OOM 杀掉,查了半天才发现是这个问题。

另外,WSL2 的磁盘 IO 性能是另一个隐藏瓶颈。模型权重读取、Docker 镜像层加载都依赖磁盘速度。如果你把模型放在机械硬盘或者移动硬盘上,加载时间会成倍增长,建议把模型文件放到 SSD 上的 NTFS 分区,或者干脆放到 WSL2 的虚拟磁盘中(比如~/models/路径)。

7. 最后再分享一个小经验

整个流程走下来,我在实际部署中发现,最容易让人心态崩溃的其实不是某个具体的报错,而是"感觉什么都配好了但就是跑不起来"的阶段。这种情况下别急着反复重装,先停下来按顺序排查:先确认 WSL2 里的nvidia-smi正常,再确认 Docker 容器里能访问 GPU,最后再检查 vLLM 启动参数。这三层链路每一层都有明确的验证命令,逐层通过就不会有问题。

还有一点想说的是,Docker 方案的好处是假设哪天你想换模型,比如从 Qwen3-8B-FP8 换成其他同规格模型,只需要替换--model参数和挂载路径,容器环境完全不用动。这个隔离性带来的便利,比原生部署省心太多了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 18:32:32

SpringBoot+Vue校园社团管理平台开发实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 18:31:51

基于SpringBoot的茶道文化传播网站的设计与实现毕业设计项目源码

温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台…

作者头像 李华
网站建设 2026/9/12 18:31:47

T4周:猴痘病识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 学习目的&#xff1a;采用CNN实现猴痘病识别 一、 前期准备 关于环境 语言环境&#xff1a;Python3.6编译器&#xff1a;vsCode深度学习环境&#xff1a;Ten…

作者头像 李华
网站建设 2026/9/12 18:29:49

ADR: [决策标题]

ADR: [决策标题] 【免费下载链接】awesome-copilot Community-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot. 项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot Context: [为什么需要…

作者头像 李华
网站建设 2026/9/12 18:28:59

Java时间处理与正则表达式实战技巧

1. Java时间与日期处理实战 在Java开发中&#xff0c;时间日期处理是每个开发者必须掌握的硬核技能。从早期的Date、Calendar到Java 8全新的时间API&#xff0c;这套体系经历了革命性的演进。我见过太多项目因为时间处理不当导致线上事故&#xff0c;今天就把这些年的踩坑经验系…

作者头像 李华