news 2026/9/17 3:40:17

Vulkan开发环境搭建全攻略:从SDK到llamacpp实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vulkan开发环境搭建全攻略:从SDK到llamacpp实战

最先给我下马威的不是渲染管线,也不是交换链,而是环境。

三周前我满心欢喜地按"Vulkan学习笔记"系列往下走,结果第一个启动示例就卡在创建实例上。前两篇还在谈实例、物理设备这些概念时觉得逻辑挺清楚,真到自己动手配环境,才发现SDK、驱动、loader、layer、glslangValidator……这些名词在文档里各占各的章节,实际操作时它们之间的关系却没人一次性讲明白。更要命的是,我后来编译llamacpp源码想用Vulkan后端也栽在同一个地方——不是代码写错,是环境根本没配全。

这篇笔记就把"搭建Vulkan开发环境"这件事从头到尾捋一遍,重点放在Windows平台,从装什么东西、为什么需要这么多东西,到用一个最小的CMake工程跑通,再到用Vulkan编译llamacpp这类真实项目的完整路径。适合刚学Vulkan、准备开始写代码但还卡在环境阶段的读者,也适合想给现有项目引入Vulkan后端、却被链接错误折磨的朋友。

1. 先说清楚:Vulkan的开发环境凭什么这么"重"

1.1 运行库、驱动和SDK是三层不同的东西

Vulkan环境让人犯迷糊的根本原因,是它把三件本该打包在一起的事情彻底分开了:底层驱动、加载器(loader)、开发SDK。

驱动是GPU厂商给的,NVIDIA、AMD、Intel各有各的包。普通用户装个最新版显卡驱动就带上了Vulkan运行时的基础部分,但运行时的driver只管"调用GPU干活"。而平时写代码include进去的vulkan.h,以及链接用的vulkan-1.lib,这些属于SDK,是LunarG维护的VulkanSDK安装包提供的。

中间还夹着一个loader,也就是vulkan-1.dll。它不干活,只负责把你的代码调用分发给各个驱动和layer。代码里写的vkCreateInstance,实际上先钻进loader,再由loader根据参数找到对应的ICD(Installable Client Driver)。

这三层里只要有一层版本不匹配,最典型的结果就是vkcube黑屏或者创建实例报"VK_ERROR_INCOMPATIBLE_DRIVER",而报错信息往往不告诉你到底是哪一层出了问题。

1.2 loader的分发逻辑:为什么装了SDK还要装驱动

我当初犯过的错,是以为装了VulkanSDK就等于有个能跑的环境,结果vkcube直接起不来。原因就是SDK里带的loader虽然有了,但它找不到可用的ICD——也就是说,系统里没有一份能匹配的GPU驱动。

Windows下loader寻找ICD的路径在注册表和系统目录里。NVIDIA和AMD的现代驱动安装后,会在系统里注册一个json文件,loader启动时扫描这些json,把对应的驱动接进来。如果你的显卡驱动太老,或者用的是核显但驱动没更新,loader扫描后得到的就是空列表,任何Vulkan应用都跑不了。

所以在Windows上配Vulkan环境的顺序,应该是:先确认GPU厂商驱动是最新的,再装VulkanSDK,然后才轮到写代码。驱动是地基,SDK是脚手架,顺序反了,报错千奇百怪。

1.3 从llamacpp源码编译往回推环境配置顺序

后来我编译llamacpp的Vulkan后端时,对这套"三层分离"的理解又深化了一层。

llamacpp走的是CMake构建,打开GGML_VULKAN选项后,它需要的是开发SDK里的头文件和库文件,运行推理时则需要loader和驱动。这意味着编译机和运行机对环境的要求不一样。很多人在编译阶段报"找不到Vulkan",其实是因为只安装了SDK,但CMake没定位到;也有的人编译阶段过了,运行起来还是报创建实例失败,那是运行机的驱动问题,跟编译没关系。

把这些串起来看,环境配置的思路就清晰了:编译期要的是头文件、lib、编译工具;运行期要的是loader和驱动;调试期还要validation layer。同一台机器上,这三套东西必须共存且版本协调。

2. 动手安装:Vulkan SDK里每个组件是干什么的

2.1 SDK安装的本质:不是"一个库",而是一套工作台

LunarG的VulkanSDK从1.2版本之后基本都是统一安装包,Windows版是exe安装向导。默认安装路径类似C:\VulkanSDK\1.3.280.0,安装完成后会帮你把VULKAN_SDK环境变量指过来,同时往PATH里加入bin目录。

很多人只看目录里的Include和Lib,忽视了其他几个关键组件,这里列一下SDK自带的主要内容:

组件用途平时用到没
Include/vulkan/vulkan.h所有API函数声明、结构体定义编译必备
Lib/vulkan-1.libWindows下的导入库,链接时用编译必备
Bin/vulkan-1.dllloader本体,运行时按参数分发给驱动运行必需
Bin/glslangValidator.exeGLSL/HLSL编译成SPIR-V的编译器写shader必备
Bin/vkcube.exe官方自带的演示程序,用来验证环境环境自检
Bin/vulkaninfo.exe打印所有Vulkan设备、队列、格式信息环境自检
Bin/VkLayer_khronos_validation.dll标准校验层开发调试必备
Bin/shaderc.exe提供glslc等工具链构建系统集成用

装完SDK,最重要的不是目录多重,而是VULKAN_SDKPATH这两个环境变量都正确。CMake的find_package(Vulkan)会读VULKAN_SDK,llamacpp这类项目也会靠它定位SDK。我见过有朋友手动改路径后漏了PATH,导致CMake找到了头文件,编译时却链不上lib的情况。

2.2 编译器与构建工具的选择

Windows上写Vulkan,编译器的选择主要影响后面链接库的体验。Visual Studio 2022的MSVC是绝大多数人的选择,原因很实际:VulkanSDK官方包装好的导入库和示例工程,默认就是MSVC工具链。MinGW GCC也能用,但在处理glslangValidator的集成、库的ABI兼容时会多出不少麻烦。

构建工具我推荐CMake,这个不用纠结。Vulkan的生态里几乎所有项目(包括llamacpp、glfw、glm)都用CMake组织,如果你还在用VS工程文件手动添加include/lib路径,建议尽早转到CMake。倒不是说手动配置不行,而是后续接入第三方库时,CMake的依赖管理能省掉大量重复劳动。

我的装机组合是:Windows 10/11 + 最新版NVIDIA驱动 + Visual Studio 2022(只装C++桌面开发组件)+ CMake 3.20以上 + VulkanSDK 1.3.x。这套组合能覆盖从学习到编译llamacpp的全部需求。

2.3 安装后第一时间要做的事:vulkaninfo与vkcube验证

SDK装完、环境变量生效(新开的终端窗口才会读到新的环境变量)之后,先别急着写代码,跑两个命令:

vulkaninfo --summary vkcube

vulkaninfo --summary会打印当前可用的物理设备、API版本、支持的队列族、扩展列表。看到gpu:下面有你的显卡名和API版本,说明loader成功找到了驱动。vkcube如果弹出一个旋转的彩色立方体窗口,说明整个链路(loader→ICD→交换链→呈现)是通的。

这两个命令通过后再进CMake工程,环境问题基本能排除掉七八成。如果vkcube就挂了,后面写再多代码都是白搭。

3. CMake接入Vulkan:推荐用官方find_package而不是手动拼路径

3.1 find_package(Vulkan)实际能拿到什么

从CMake 3.10开始,官方就自带了Vulkan的查找模块。你在CMakeLists.txt里写一行:

find_package(Vulkan REQUIRED)

CMake会在几个地方搜索Vulkan组件:环境变量VULKAN_SDK指向的目录、系统的默认库路径、注册表信息。找到之后,会生成一个名为Vulkan::Vulkan的导入目标,包含了include目录和link库。

这在Windows上最省心的地方在于,它会自动找到SDK里正确的导入库。值得提一下的是,find_package(Vulkan)默认找的是Vulkan::Vulkan,这是loader的导入库。如果你还要处理validation layer的扩展、shader编译,那是另外的环节,别把它们混在一起。

链接时只要写:

target_link_libraries(your_target PRIVATE Vulkan::Vulkan)

头文件和库文件就都有了。

3.2 手动链接vulkan-1.lib时我踩过的坑

我最早在VS里配环境时,是老老实实手动加Include目录、加lib路径、再把vulkan-1.lib填进附加依赖项里。这种方法在小例子里没问题,但一旦项目变大、目录调整,坑就出现了。

第一个坑:x64和Win32的lib混用。VulkanSDK同时带x64和Win32两个子目录的lib,你给VS配置时如果选了错误的架构下的lib,链接阶段会报LNK1112: module machine type 'x64' conflicts with target machine type 'x86'。这个报错在不同机器上显示格式略有差异,但根本原因一致:架构不匹配。

第二个坑:动态库和静态库混淆。VulkanSDK里只有一个导入库vulkan-1.lib,它对应的是动态链接vulkan-1.dll。有的老教程会说"用SDK自带的静态库libvulkan.a"——那是Linux或MinGW环境下的东西,Windows上用错了地方,链接时的符号解析就会出各种奇怪问题。

用find_package之后,这些架构、路径问题都由CMake模块处理,人脑去记这些匹配关系没有任何价值。

3.3 用GLM+GLFW搭出的最小CMake测试工程参考

一个最小可运行的测试工程,我用的是GLFW做窗口、GLM做数学库,结构非常简单:

vulkan_test/ CMakeLists.txt src/main.cpp

CMakeLists.txt内容:

cmake_minimum_required(VERSION 3.20) project(vulkan_test) set(CMAKE_CXX_STANDARD 17) find_package(glfw3 REQUIRED) find_package(Vulkan REQUIRED) add_executable(vulkan_test src/main.cpp) target_link_libraries(vulkan_test PRIVATE glfw Vulkan::Vulkan)

这段配置里find_package(glfw3 REQUIRED)需要提前装好GLFW。Windows下最简单的方式是用vcpkg装,或者在CMake里用FetchContent拉源码。如果暂时不想引入GLFW,也可以先用Win32的CreateWindow创建窗口,但为了后续交换链和呈现方便,直接用GLFW更省事。

main.cpp里暂时只做一件事:创建Vulkan实例后释放,跑通"SDL/GLFW初始化→Vulkan实例创建→销毁"这条链路:

#define GLFW_INCLUDE_VULKAN #include <GLFW/glfw3.h> #include <iostream> int main() { glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(800, 600, "Vulkan Test", nullptr, nullptr); VkApplicationInfo appInfo{}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "Hello Vulkan"; appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.apiVersion = VK_API_VERSION_1_3; VkInstanceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; VkInstance instance; if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) { std::cerr << "Failed to create instance." << std::endl; glfwTerminate(); return -1; } std::cout << "Vulkan instance created." << std::endl; vkDestroyInstance(instance, nullptr); glfwDestroyWindow(window); glfwTerminate(); return 0; }

这个程序能打印出"Vulkan instance created.",我的底线就算达到了,说明头文件、lib、loader、驱动这条链路是通的。这里明显能看到vulkan.h里的API和后端驱动的对应关系——vkCreateInstance先进入loader,loader再根据ICD信息找到驱动创建实例,哪个环节断了,程序都会在这里失败。

4. 写了第一个Instance程序,怎么确认环境真的可用

4.1 按层拆解:从vkCreateInstance到枚举物理设备

实例创建成功只是最基本的一步,接下来必须确认物理设备能被枚举出来,否则后续的队列和交换链都是空中楼阁。

物理设备枚举代码非常短:

uint32_t deviceCount = 0; vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr); std::vector<VkPhysicalDevice> devices(deviceCount); vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()); for (const auto& dev : devices) { VkPhysicalDeviceProperties props; vkGetPhysicalDeviceProperties(dev, &props); std::cout << "Device: " << props.deviceName << std::endl; std::cout << "API: " << VK_API_VERSION_MAJOR(props.apiVersion) << "." << VK_API_VERSION_MINOR(props.apiVersion) << std::endl; }

这一步能在相当程度上暴露环境问题:如果deviceCount是0,说明loader虽然找到了,但驱动层没有可用物理设备。这种情况常见于老显卡驱动不完整,或者笔记本上有双显卡直接用了核显路径。

跑这段代码时我习惯同时看vulkaninfo --summary的输出做对照:应该能看到一模一样的显卡型号和API版本。两者对不上,说明程序找的设备路径跟vulkaninfo不一样,优先查PATH里的dll是不是被系统目录里的旧loader覆盖了。

4.2 VK_LOADER_DEBUG=all是排查问题的最佳武器

如果物理设备枚举失败,或者创建实例失败,别急着改代码,先给环境变量灌一个调试开关:

set VK_LOADER_DEBUG=all

再运行程序,loader会在控制台输出一长串详细日志,包括它扫描了哪些ICD文件、找到了几个驱动、加载了哪些layer。这些信息是定位"为什么Vulkan环境有问题"的最直接线索。

日志里最值得关注几类输出:搜索到的manifest json文件路径、加载失败的dll名字、被跳过的ICD原因。我遇到过的典型问题是笔记本双显卡切换导致NVIDIA的json找到了但dll加载失败,从日志一眼就能看出来,远比自己瞎猜快得多。

调试完记得把这个环境变量清掉,否则所有Vulkan程序启动时会带着大量日志输出,虽然不影响功能,但有性能损耗,旧机器上能明显感到掉帧。

4.3 验证颜色空间和队列族的常见误区

环境验证只走到物理设备还不够,至少还要确认两件事:图形队列族存在、交换链基本格式可用。

检查队列族:

uint32_t queueFamilyCount = 0; vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr); std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount); vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data()); for (uint32_t i = 0; i < queueFamilyCount; i++) { if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { std::cout << "Graphics queue family index: " << i << std::endl; } }

这一步是要确认驱动愿意提供支持图形命令的队列。几乎没有现代GPU会不提供图形队列,但如果你的程序加载了某些奇怪的成层组合,理论上可能出现队列家族全部不满足所需标志的情况。

交换链格式检查则直接依赖物理设备的表面能力:

VkSurfaceCapabilitiesKHR caps; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &caps); std::cout << "Min image count: " << caps.minImageCount << std::endl; std::cout << "Current extent: " << caps.currentExtent.width << "x" << caps.currentExtent.height << std::endl;

这里容易踩的坑是直接写死某个格式(比如VK_FORMAT_B8G8R8A8_UNORM),但不同的显示器、不同的合成模式可能给出不同的首选格式。环境验证阶段最好用vkGetPhysicalDeviceSurfaceFormatsKHR把支持的格式枚举出来,再从中选一个可用的。这一步与其说是验证环境,不如说是提前避掉渲染代码里的"硬编码假设"。

5. GGML_VULKAN=ON:llamacpp源码在Windows下编译的完整链路

5.1 CMake配置阶段:SDK没找到时的真实报错

把环境验证没问题,就可以拿真实项目来试刀了。llamacpp是目前最常见的、以C++为主且带Vulkan后端的开源项目之一,编译它的Vulkan版本,等于一次综合性的环境压力测试。

在源码根目录执行:

cmake -B build -DGGML_VULKAN=ON -DCMAKE_BUILD_TYPE=Release

GGML_VULKAN=ON会让ggml的CMake逻辑进入Vulkan后端分支,然后再次调用find_package(Vulkan)。如果这个阶段报Could NOT find Vulkan (missing: Vulkan_INCLUDE_DIR),通常原因是环境变量VULKAN_SDK没设对,或者CMake的缓存里记住了旧路径。

保证能找到的做法之一是显式指定SDK路径:

cmake -B build -DGGML_VULKAN=ON -DCMAKE_PREFIX_PATH="C:/VulkanSDK/1.3.280.0" -DCMAKE_BUILD_TYPE=Release

网络上有不少llamacpp编译教程会建议"把vulkan-1.lib拷到某个目录"之类的土办法,那都是舍近求远。只要VULKAN_SDK环境变量正确,CMake官方模块自己就能找到所有东西。

5.2 SPIR-V编译环节为什么会卡在glslangValidator

CMake配置和编译过程中,llamacpp的Vulkan后端有一块是大部分入门教程不会主动提到的:shader离线编译成SPIR-V。

llamacpp的Vulkan实现里,大量自定义kernel是以.comp为后缀的GLSL shader写的,构建时必须用glslangValidator把它们编译成SPIR-V二进制,再嵌进程序。这个环节如果SDK的bin目录没进PATH,CMake阶段就会报错,大意是找不到glslangValidator可执行文件。

很多人把这里的失败误以为是C++编译问题,其实不是。解决办法很简单,确认PATH里包含C:\VulkanSDK\<版本>\bin,然后重新进行CMake配置。

编译成功之后,可执行文件通常生成在build/bin/Release/目录下,名字类似llama-vulkan.exe等。这里要特别提醒:这个可执行文件运行的时候,还是需要一个能加载Vulkan驱动的loader。如果拿到另一台没装过VulkanSDK的机器上跑,必须先装GPU厂商驱动(驱动会带上vulkan loader)或者把SDK的bin目录下的vulkan-1.dll放到exe同目录。

5.3 编译成功不等于能跑:Runtime加载Vulkan时的三个坑

llamacpp的Vulkan后端跑起来之后,第一次启动会在日志中打印后端名称和物理设备信息,类似:

ggml_vulkan: Found 1 Vulkan devices: ggml_vulkan: 0 = NVIDIA GeForce RTX 3060 (NVIDIA) ggml_vulkan: picking device 0

如果这行日志没出现,程序可能在加载阶段就以非零码结束了,问题往往在这几个方面。

第一个坑是机器上没有可用的Vulkan驱动。有些精简版Windows或者旧机器,系统本身没装GPU厂商驱动,只有微软的基础显示驱动。这种驱动不提供Vulkan支持,程序怎么折腾都创建不了实例。

第二个坑是双显卡环境选了错误的物理设备。llamacpp在默认情况下会选设备0,如果你的设备0是核显,性能表现会大打折扣。推理时的参数可以指定设备索引,具体参数名用--help查看,一般能看到类似设备列表的选项。

第三个坑是显存不足时的分配失败。Vulkan后端和CUDA不同点在于,它倾向于把模型层完整放上GPU,显存不够就直接报分配失败,而不是像CUDA那样有offload层数的精细控制。运行前先看一眼模型大小和显卡显存,避免加载到一半崩掉。

5.4 Vulkan后端在推理中的资源表现

环境配好、程序跑通后,值得对比一下Vulkan后端和CPU后端在资源利用上的差异。llamacpp的Vulkan后端把主要计算交给GPU,CPU端只负责调度和token处理。实测下来,对于一个7B左右的量化模型,显存占用大约在4-6GB之间(具体取决于量化格式和上下文长度),比CUDA版本在某些场景下稍高一些,但胜在NVIDIA、AMD、Intel显卡通吃,不需要为特定GPU厂商专门配CUDA工具链。

从编译和运行的整个链路来看,Vulkan后端的价值不只是"能用GPU跑模型",而是它让同一套代码在不同厂商的GPU上都能跑。这对开发环境的包容性要求高,但对最终用户来说反而更方便——不用关心对方用的是哪家的显卡。

6. 环境搭建的检查清单:照着过一遍,省掉半天排查

6.1 从SDK环境变量到运行时创建,逐项自检

如果你照着前面的流程走完还是遇到问题,下面这个自检清单是我排查环境问题的固定顺序,每项都对应一个具体的检查点和修复手段:

检查项验证方法问题定位
GPU驱动是否支持VulkanNVIDIA驱动面板或vulkaninfo --summary驱动版本过旧或不含Vulkan runtime
VULKAN_SDK环境变量echo %VULKAN_SDK%未安装SDK或安装完成后未重启终端
PATH是否含SDK的binwhere vulkaninfovulkaninfo找不到说明PATH不对
loader能否识别ICDset VK_LOADER_DEBUG=all后跑vkcube日志中ICD加载失败
实例能否创建跑第3节的最小程序查看VK_ERROR_EXTENSION_NOT_PRESENT等返回值
validation layer是否加载VK_INSTANCE_LAYERS环境变量或代码内启用layer路径不对或版本与SDK不匹配
CMake能否找到SDKcmake --find-package -DNAME=Vulkan -DCOMPILER_ID=MSVC手动指定CMAKE_PREFIX_PATH

这串清单我每次换机器、换系统、升级SDK之后都会完整过一遍,总共不到五分钟,但能省掉后面无数的"为什么我这边编译不过去"。

6.2 新手最容易出现的三类环境问题速查

第一类是链接问题。报错形式一般是LNK2019 unresolved external symbol vkCreateInstance referenced in function main。原因通常是漏了vulkan-1.lib这个导入库,或者链接的是错误的架构版本。修复方法就是改用find_package(Vulkan),让CMake自动配好。

第二类是运行时创建实例失败,报VK_ERROR_INCOMPATIBLE_DRIVERVK_ERROR_EXTENSION_NOT_PRESENT。前者代表loader找到驱动但不能用,优先更新显卡驱动;后者代表启用了不存在的扩展,往往是复制了网上的老代码,扩展名没改对(比如把VK_KHR_surface写成了VK_KHR_SURFACE,大小写不对)。

第三类是validation layer报一大串错误但程序能跑。这其实算"配置成功"的副作用——校验层被正确加载了,它在帮你找出代码里的细节问题。如果这一层没加载,反而说明你的调试环境缺了重要一环。加载方式是开启VK_LAYER_KHRONOS_validation扩展,同时在创建实例时把这个layer加进ppEnabledLayerNames。

6.3 关于环境这关,我的体会

配环境这件事,最反直觉的一点是:越想把每一个组件都理解得透透彻彻再动手,越容易卡壳。Vulkan这套东西组件多、关系绕,但按照"驱动→SDK→loader→验证"的顺序一路装下来再验证,其实踩不了几次坑。

我个人的做法是:环境搭建好后,把第一条命令vulkaninfo --summary和vkcube的截图保存一份,以后报错的时候对照"没报错时是什么输出",能帮我快速区分到底是环境坏了还是代码坏了。这个方法笨,但特别可靠。

llamacpp编译成功后,我用Vulkan后端跑通了第一个7B模型的推理,那一刻才觉得环境这关算正式过了。但也就是从那一刻起,我开始面对Vulkan的真正难点——管道对象、描述符、命令缓冲区,这些才是接下来需要啃的硬骨头。

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

BMC开发必知:PSL remote_file_send()函数解析与‘无效会话ID’排查

做BMC开发的兄弟&#xff0c;十有八九都跟PSL打过交道。今天要聊的是PSL函数库里的remote_file_send()——准确说是第65号函数&#xff0c;一个干“远程传文件”这个活儿的封装。别小看它&#xff0c;很多固件升级、日志采集、配置备份的自动化脚本都靠它跑起来。我第一次接触这…

作者头像 李华
网站建设 2026/9/17 3:39:01

基于Java的羽毛球馆管理系统:Spring Boot预约设计与并发控制实战

1. 先搞清楚这个“管理系统”到底要管什么——需求边界与应用场景很多人一看到“基于Java的羽毛球馆管理系统”&#xff0c;第一反应就是“又是一个XX管理系统&#xff0c;老套路了”。说实话&#xff0c;我刚接到这个题目的时候也是这么想的&#xff0c;但真正开始梳理需求之后…

作者头像 李华
网站建设 2026/9/17 3:37:50

群晖NAS上部署Home Assistant:Docker容器实现智能家居中枢全攻略

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

作者头像 李华
网站建设 2026/9/17 3:37:29

大模型系统战:本地部署、RAG、微调与安全落地的工程实践

1. 大模型的下半场&#xff0c;已经从“模型竞赛”转向“系统竞赛”过去一年&#xff0c;做技术规划和产品立项的人应该都有一个共同感受&#xff1a;公开渠道能拿到的大模型&#xff0c;能力和价格都在快速内卷&#xff0c;但真正能稳定跑出业务价值的项目&#xff0c;反而没有…

作者头像 李华
网站建设 2026/9/17 3:37:16

AI Agent不能加速ANSYS求解器内核,但能重构仿真工作流

1. 一个被反复误读的“加速”幻觉&#xff1a;为什么ANSYS求解器内核根本无法被AI Agent“提速”去年底&#xff0c;我帮一家做电机电磁仿真的客户部署一套AI辅助工作流系统。他们采购了三台高性能计算节点&#xff0c;又额外买了两套PyAEDT企业License&#xff0c;目标很明确&…

作者头像 李华