在 AgentX 这类智能体推理场景里,CUDA 已经不只是“GPU 编程接口”,而是从训练到部署、从算子到框架、从驱动到容器的一整条生态链条。很多人关心“CUDA 护城河能否守住智能体推理”,但真正要回答这个问题,绕不开几个基础工程事实:CUDA 运行时和驱动如何配合,AgentX 推理基准到底测哪些指标,显卡、驱动、Toolkit、框架版本不一致时会产生什么现象,以及换到非 CUDA 平台后同样的推理代码还能不能跑出同等效果。
这篇文章从工程实践角度切入,先把 CUDA 在智能体推理中扮演的角色拆清楚,再给出基于 AgentX 思路的推理基准搭建、环境配置、代码实现和结果解读方法。最后会讨论所谓护城河到底由哪些层构成,以及哪些场景下它仍然坚不可摧,哪些场景里它正在被逐步削弱。
1. 智能体推理为什么绕不开 CUDA
1.1 智能体推理和传统模型推理的区别
传统模型推理通常指输入一段文本、一张图片或一个特征向量,模型前向传播一次后给出输出。智能体推理不一样。AgentX 这类智能体在推理时往往需要:
- 多轮对话与上下文维护
- 调用工具、检索知识库、执行代码
- 在多个模型或策略之间切换
- 根据中间结果动态调整推理路径
这意味着推理过程不再是固定的“输入 -> 输出”链路,而是一棵不断分叉的决策树。每一次决策都可能触发新的模型调用,每个模型调用都是一次 GPU Kernel 执行。因此智能体推理的瓶颈往往不是单一模型的单次前向时间,而是整条链路在 GPU 上的调度效率、显存占用模式、算子执行密度以及框架层的任务切换开销。
CUDA 在这条链路中的位置非常底层。它提供了 GPU 设备的管理抽象,负责把模型算子映射到具体流处理器上执行。无论上层是 PyTorch、TensorFlow 还是 TensorRT,最终都要通过 CUDA 运行时和显卡驱动把 Kernel 提交给 GPU。这也是为什么讨论智能体推理时,CUDA 版本、驱动版本、显卡算力这些底层参数经常成为排查问题的关键。
1.2 CUDA 在智能体推理链路中占据的位置
在普通开发视角里,CUDA 被简写成“PyTorch 里那个能够加速计算的版本标志”。实际在一个完整推理链路里,CUDA 相关组件至少包括:
| 层次 | 组件 | 作用 |
|---|---|---|
| 硬件抽象层 | NVIDIA 显卡驱动 | 管理 GPU 设备、显存、中断、上下文 |
| 运行库层 | CUDA Toolkit | 提供 nvcc 编译器、CUDA Runtime、调试工具、算子库 |
| 加速库层 | cuBLAS、cuDNN、TensorRT | 优化矩阵乘、卷积、推理引擎等高密度计算 |
| 框架适配层 | PyTorch、TensorFlow、自定义 C++ 封装 | 调用 CUDA API 或算子库完成模型推理 |
| 容器编配层 | NVIDIA Container Toolkit | 让 Docker 容器内感知 GPU 设备 |
智能体推理通常不会直接编写 CUDA C++,而是通过 PyTorch 等框架调用。但框架背后的 cuDNN、cuBLAS、TensorRT 都依赖 CUDA Runtime 和驱动版本。版本错位时,现象可能非常隐蔽:有时是程序启动直接报错,有时是推理速度突然下降,有时是显存无法分配,有时是容器内nvidia-smi正常但 PyTorch 仍然显示 CUDA 不可用。
对 AgentX 这类需要长链路推理的系统来说,底层这些依赖必须提前对齐,否则所谓的“CUDA 护城河”还没有影响到竞争对手,就已经先变成了自己的部署障碍。
2. AgentX 推理基准的核心指标与测试思路
2.1 推理基准测的不是跑分,而是决策链路的稳定性
AgentX 推理基准关注的重点并不只是“单次请求延迟多少毫秒”。智能体推理中有几个更贴近业务真实的指标:
- 端到端延迟:从智能体收到用户问题到最终回答完成的总时长,包括多轮调度和多次模型调用。
- 工具调用开销:智能体在决定调用工具并等待工具返回值时,GPU 是否会产生空闲、显存是否长时间占用。
- 并发能力:当多个智能体会话同时进行时,GPU 显存、Kernel 调度和框架锁竞争是否导致吞吐下降。
- 长上下文稳定性:上下文变长后,KV Cache 显存占用曲线是否可控,是否频繁触发 OOM。
- 失败恢复代价:某个模型调用超时或显存不足时,智能体链路能否回退,回退后是否需要重新加载权重。
这些指标不像传统跑分那样能简单画成一条性能曲线,但它们在真实生产环境里更关键。CUDA 生态的优势在于,跑这些指标时底层算子和显存管理已经经过了大量优化;劣势在于,一旦环境复杂化,排查和稳定的难度也会同步上升。
2.2 AgentX 基准场景下的典型 GPU 资源模型
假设一个中等规模的智能体配置:一个 7B 参数对话模型,一个用于意图识别的较小模型,一个用于任务规划的模型,加上外部工具调用。一次完整对话可能产生如下资源变化:
| 阶段 | GPU 负载 | 显存变化 | CUDA 特征 |
|---|---|---|---|
| 意图识别 | 低 | 小幅上升 | 小 Kernel 密集,启动开销占比高 |
| 上下文编码 | 高 | 线性增加 | 矩阵乘和 Attention 密集 |
| 工具调用 | 中 | 开销平稳 | 等待外部 I/O 时 GPU 利用率下降 |
| 结果生成 | 高 | KV Cache 增长 | 逐 Token 生成, Memory Bound 明显 |
| 多会话并发 | 高 | 多上下文叠加 | 显存分配和请求调度成为瓶颈 |
在这个模型下,所谓“CUDA 护城河”体现为:矩阵乘、Attention、KV Cache 管理等操作都能在 CUDA 生态里找到高性能实现,智能体框架不需要自己编写底层算子。而在非 CUDA 平台上,往往要么性能差距明显,要么需要手动适配算子,研发成本会显著上升。
3. 搭建 AgentX 推理基准的 CUDA 环境
3.1 先理解驱动、Toolkit、框架三者的版本关系
搭建环境前最容易踩的坑是混淆显卡驱动和 CUDA Toolkit。驱动负责让操作系统识别显卡并提供设备管理能力;CUDA Toolkit 是开发运行环境,包含 nvcc、运行时库、数学库。框架调用 CUDA 时,既需要驱动支持,也需要 Toolkit 中的运行库能匹配驱动接口。
三者的兼容关系可以简化成:
- 驱动支持较旧版本的 Toolkit,但不一定支持最新版本。
- 新驱动通常向下兼容旧 Toolkit。
- PyTorch 等框架预编译包会绑定某个 CUDA 版本,例如 cu121、cu124。
- CUDA 驱动和 Toolkit 不匹配时,常见现象是程序找不到 libcudart,或者运行时提示驱动版本过低。
AgentX 基准环境最稳妥的组合方式是:先确认显卡算力,再根据算力选择 CUDA Toolkit 版本,再选择驱动版本,最后选择对应框架的预编译包。反向操作很容易出现“框架要求 CUDA 12.1,但驱动的 CUDA 版本只支持到 11.8”这类问题。
3.2 Ubuntu 22.04 下安装 CUDA Toolkit 和 NVIDIA 驱动的示例
下面示例用于说明思路,实际执行前需要结合自己的驱动版本和 CUDA 版本调整。
先查看 GPU 设备型号和驱动状态:
lspci | grep -i nvidia nvidia-smi如果nvidia-smi不存在,需要先安装驱动。Ubuntu 下可以用系统仓库安装,也可以使用 NVIDIA 官方 runfile。推荐先使用系统仓库,因为卸载和回滚更简单:
sudo apt update sudo apt install nvidia-driver-535 sudo reboot重启后再执行nvidia-smi,确认驱动识别成功。
然后安装 CUDA Toolkit。以 CUDA 12.4 为例,在官方仓库配置完成后执行:
sudo apt install cuda-toolkit-12-4安装完成后检查版本:
nvcc --version这里要注意,nvcc --version显示的是 CUDA Toolkit 版本,nvidia-smi右上角显示的 CUDA 版本是驱动支持的最高 CUDA 版本,两者含义不同。
注意:
nvidia-smi右上角显示的“CUDA Version”并不是当前已安装的 Toolkit 版本,而是该驱动能够兼容的最高 CUDA 版本。很多环境问题都源于对这个信息的误解。
3.3 WSL2 和容器环境下的 CUDA 适配
智能体推理经常需要部署在 WSL2 或 Docker 容器中。WSL2 的 CUDA 支持依赖于 Windows 侧安装的 NVIDIA 驱动。在 WSL2 内不需要额外安装 Linux 驱动,但要安装 CUDA Toolkit。WSL2 内执行nvidia-smi时,实际访问的是 Windows 侧的驱动。
Docker 容器场景则需要注意,镜像里安装的 CUDA 组件和宿主机驱动之间的关系是:
- 宿主机只装显卡驱动。
- 容器内必须包含 CUDA Toolkit 和运行库。
- 容器内的 CUDA 版本需小于等于宿主机驱动支持的 CUDA 版本。
- 容器需要借助 NVIDIA Container Toolkit 才能访问 GPU。
配置 NVIDIA Container Toolkit 后运行容器:
docker run --gpus all --rm nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi正常情况下能看到 GPU 信息。如果容器内无法识别 GPU,优先检查宿主机是否安装了 NVIDIA Container Toolkit,以及容器运行时是否为nvidia。
应对不同环境时,可以参照下面的对应关系表:
| 环境 | 驱动安装位置 | CUDA Toolkit 安装位置 | 主要风险 |
|---|---|---|---|
| Ubuntu 22.04 物理机 | 宿主机 | 宿主机 | 驱动和 Toolkit 版本错配 |
| WSL2 | Windows 侧 | Linux 发行版内 | 忘记在 Windows 侧升级驱动 |
| Docker | 宿主机 | 镜像内 | 未安装 Container Toolkit |
| 麒麟 V10 | 宿主机 | 宿主机 | 仓库源差异,需要适配内核 |
4. AgentX 推理基准的最小实现
4.1 用 PyTorch 构建一个可复现的推理测试脚本
AgentX 本身可以是一个调度框架,但这里不依赖具体产品,而是用一组标准化的 PyTorch 推理代码模拟 AgentX 的典型链路。下面示例模拟了三段式智能体推理:意图识别、模型调用、结果生成。
实现前先确认 PyTorch 能正常使用 CUDA:
import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))如果输出torch.cuda.is_available()为False,需要先回到环境配置章节检查驱动和 Toolkit 版本。
下面是最小推理基准脚本的核心结构:
import time import torch from transformers import AutoModelForCausalLM, AutoTokenizer device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model_name = "Qwen/Qwen2-7B-Instruct" # 示例模型,实际按需调整 tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForCausalLM.from_pretrained( model_name, torch_dtype=torch.float16, device_map="auto" ) def run_inference(prompt, max_new_tokens=256): inputs = tokenizer(prompt, return_tensors="pt").to(device) start = time.time() with torch.no_grad(): outputs = model.generate( **inputs, max_new_tokens=max_new_tokens, do_sample=False ) elapsed = time.time() - start generated = tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokens=True) return generated, elapsed prompt = "请根据用户需求调用天气工具,并返回出行建议。" result, elapsed = run_inference(prompt) print(f"生成结果: {result}") print(f"推理耗时: {elapsed:.2f}s")这里把模型放在 GPU 上,使用半精度减少显存占用,并用torch.no_grad()关闭梯度计算。对于智能体推理基准,更重要的是循环记录多次请求的延迟、显存峰值和吞吐量,而不是只测单次结果。
4.2 记录显存和延迟数据的增强版脚本
为了给 AgentX 推理基准提供可量化数据,可以在脚本中加入显存统计和并发测试:
import threading import torch import time from queue import Queue results = Queue() def benchmark_thread(prompt, model, tokenizer, device): inputs = tokenizer(prompt, return_tensors="pt").to(device) torch.cuda.synchronize() start = time.time() with torch.no_grad(): outputs = model.generate(**inputs, max_new_tokens=128, do_sample=False) torch.cuda.synchronize() elapsed = time.time() - start current_mem = torch.cuda.memory_allocated() / 1024**2 results.put({"latency": elapsed, "memory_mb": current_mem})通过这个脚本,可以观察到:
- 多次推理延迟是否有明显波动。
- 显存是否随着时间线性增长。
- 多线程并发时是否存在锁竞争或显存不足。
- CUDA 事件同步对测量精度的影响。
这里有一个实际项目里很容易忽略的细节:如果不调用torch.cuda.synchronize(),由于 GPU 异步执行,CPU 侧记录的时间可能远小于真实 GPU 计算时间。时间统计前必须执行同步操作。
4.3 测试结果如何判断“通过”
AgentX 推理基准不是只追求低延迟,还需要验证几个稳定性指标:
| 指标 | 测试方式 | 合格标准参考 |
|---|---|---|
| 单次推理延迟 | 连续运行 50 次取 P95 | 波动不超过平均值的 30% |
| 显存峰值 | 统计memory_allocated和memory_reserved | 不超过显卡显存 85% |
| 并发扩容 | 从 1 路并发逐步增加到 8 路 | 延迟不出现非线性爆炸 |
| 长上下文 | 输入长度从 512 增加到 8192 | 显存增长趋势可控,无 OOM |
| 工具调用场景 | 在推理循环中注入外部等待 | GPU 利用率回落和恢复正常 |
这里的合格标准需要结合具体模型和显卡型号调整,但测试思路是一致的:智能体推理系统的稳定性比单次跑分更重要。如果环境配置有问题,通常不会只在一个指标上体现,而是延迟波动、显存异常、并发失败多个现象同时出现。
5. CUDA 生态中的常见坑与排查路径
5.1 PyTorch 显示 CUDA 不可用
现象:torch.cuda.is_available()返回False,或者程序启动时报错 “Torch not compiled with CUDA enabled”。
排查路径:
- 执行
nvidia-smi,确认驱动是否正常输出 GPU 信息。 - 如果驱动正常,检查 PyTorch 是否安装了 CUDA 版本。
- 确认 Python 环境中是否安装了多个 PyTorch 副本。
- 执行
python -c "import torch; print(torch.version.cuda)"查看编译时 CUDA 版本。
常见原因包括:安装了 CPU 版 PyTorch、虚拟环境切换后 CUDA 依赖丢失、驱动版本过低。
5.2 nvidia-smi 正常但 CUDA 程序报错
现象:nvidia-smi能输出 GPU 信息,但运行 PyTorch 或 CUDA 程序时报错 “CUDA driver version is insufficient”。
原因通常是 CUDA Toolkit 使用的运行库版本高于驱动支持的 CUDA 版本。例如驱动支持的 CUDA 版本是 11.8,但程序编译或链接时使用的是 CUDA 12.1 的库。
解决方案:
- 升级驱动到更高版本。
- 或者安装与驱动匹配的 CUDA Toolkit。
- 或者使用框架提供的旧 CUDA 版本预编译包。
5.3 容器内无法识别 GPU
现象:Docker 容器内运行nvidia-smi报错 “could not select device with uuid”,或者容器内根本看不到/dev/nvidia0。
排查顺序:
- 宿主机执行
nvidia-smi确认驱动正常。 - 确认宿主机安装了 NVIDIA Container Toolkit。
- 确认容器启动参数包含
--gpus all。 - 查看容器运行时是否为
nvidia。
如果使用 Docker Compose,需要确保配置中包含 GPU 资源申明:
services: agentx-bench: image: my-agentx-image:latest deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu]5.4 CUDA 与 cuDNN 的关系容易混淆
CUDA 提供了底层并行计算能力,cuDNN 是构建在 CUDA 之上的深度神经网络加速库。PyTorch 在支持 GPU 时并不仅仅调用 CUDA,还会调用 cuDNN 中的卷积、池化、激活等算子。如果 cuDNN 与 CUDA 版本不匹配,可能出现运行报错或性能异常。
实际项目中,直接使用 PyTorch 官方预编译包时,cuDNN 已经内置在包里,不需要单独安装。只有在手动编译 PyTorch 或使用 TensorRT 时才需要特别注意 cuDNN 版本匹配。
5.5 更换显卡或迁移 CUDA 项目时的兼容性问题
常见场景是从 RTX 30 系列迁移到 RTX 40 系列,或者从国产 GPU 环境迁移回 CUDA。此时容易出现以下问题:
| 现象 | 原因 | 处理 |
|---|---|---|
| SM 架构不兼容 | 新旧显卡算力不同,旧代码编译时指定的-arch不匹配 | 重新编译,使用-arch=native或自动检测 |
| cuDNN 版本校验失败 | cuDNN 对架构支持范围不同 | 升级或降级 cuDNN |
| 显存容量变化后 OOM | 迁移后显存变小,原 batch size 无法放下 | 调整 batch size,开启梯度检查点或量化 |
| 设备编号错乱 | 多卡机器识别顺序变化 | 使用CUDA_VISIBLE_DEVICES固定设备 |
6. CUDA 护城河到底由什么构成,能不能守住
6.1 护城河不只来自硬件,还来自生态协同
如果只看硬件算力,NVIDIA GPU 的领先优势未必能长期保持。但从 AgentX 推理基准的实践来看,CUDA 真正的护城河由多层因素叠加形成:
- 底层算子库的成熟度:cuBLAS、cuDNN、TensorRT 经过大量场景打磨,许多算子的性能已经接近硬件理论峰值。
- 框架适配的默认路径:PyTorch、TensorFlow、JAX 对 CUDA 的适配最完善,新模型和新算子往往优先支持 CUDA。
- 工具链的完整性:nsys、ncu、Nsight Systems 等性能分析工具能帮助开发者快速定位 GPU 瓶颈。
- 工程经验的积累:网上大量的 CUDA 安装、排错、性能优化资料,社区试错成本相对更低。
- 部署链路的统一:驱动、容器、云实例、混合云环境对 CUDA 的兼容性经过大量验证。
这些因素不是某一家公司短期内能模仿的。智能体推理领域,AgentX 这类框架可能很容易替换掉模型层,但替换底层 CUDA 生态的成本要高得多。
6.2 推理基准视角下,哪些环节最容易被替代
虽然 CUDA 生态强大,但并非所有环节都不可替代。从 AgentX 推理基准的实际操作中可以看到:
- 纯计算密集的矩阵乘和 Attention:CUDA 优势明显,但在专用 AI 芯片上也可能实现接近的性能。
- 框架层 API:PyTorch 等框架已经在支持 ROCm、CPU、特定 AI 芯片后端,上层代码迁移成本并不高。
- 推理调度和 Agent 逻辑:这些发生在模型之外,与 CUDA 没有直接关系。
- 小算子密集场景:当推理链路由大量小 Kernel 组成时,Kernel 启动开销占比上升,CUDA 的性能优势会被稀释。
这意味着,如果未来智能体推理的瓶颈从“计算”转移到“调度”和“多模型协同”,CUDA 的护城河仍然存在,但它的重要性会从“唯一选择”变成“性能参考基准”。
6.3 迁移到非 CUDA 平台时,最现实的成本是什么
在 AgentX 推理基准中运行过 CUDA 环境后,如果考虑迁移到非 CUDA 平台,真正的成本往往不是代码语法,而是以下几类:
| 成本类型 | 具体表现 |
|---|---|
| 算子适配 | 模型中的自研算子需要逐一迁移或寻找替代实现 |
| 性能调优 | 相同算子在不同硬件上最优实现差异大 |
| 兼容性验证 | batch size、精度、显存策略都需要重新测试 |
| 工具链缺失 | 性能分析、错误排查、内存检测等工具需要换一套 |
| 团队经验 | 开发者对 CUDA 工具链的熟悉程度无法自动迁移 |
对于 AgentX 这类智能体推理项目,如果核心价值在 Agent 逻辑、调度策略和工具调用编排,那么底层迁移成本是可控的。如果要追求极致性能,迁移成本则会显著上升。
6.4 结论:护城河仍在,但入口在变宽
从 AgentX 推理基准的实践来看,CUDA 护城河短期内很难被完全替代,因为它的竞争力来自软硬件协同和生态积累,而不是单纯芯片性能。但在智能体推理这个新赛道上,推理形态正在变化:
- 传统单模型推理的 Kernel 密集特征会被多模型协作、工具调用、外部 I/O 等待摊薄。
- 智能体链路的长尾延迟可能来自调度等待和网络开销,而不是 GPU 算力不足。
- 推理引擎正在向“多后端统一抽象”方向发展,CUDA 会逐渐变成其中一个后端,而不是唯一后端。
对开发者来说,与其争论“护城河能不能守住”,不如做好两手准备:在 CUDA 环境下把性能和稳定性做到位,同时保持上层代码的可移植性。这样无论底层生态怎么发展,AgentX 这类框架都能以较低成本切换到对新硬件支持更好的后端。
7. 智能体推理基准的最佳实践与扩展方向
7.1 环境管理清单
实际搭建 AgentX 推理基准前,建议按以下清单逐项确认:
- GPU 型号和算力:
nvidia-smi获取设备名和驱动版本,再查算力对应表。 - CUDA Toolkit 版本:执行
nvcc --version确认。 - PyTorch 相关版本:执行
python -c "import torch; print(torch.__version__, torch.version.cuda)"。 - cuDNN 版本:如果单独使用,执行
python -c "import torch; print(torch.backends.cudnn.version())"。 - 显存容量和可用空间:执行
torch.cuda.get_device_properties(0)。 - 容器环境是否保留 GPU:执行容器内
nvidia-smi。 - 环境变量是否污染:检查
CUDA_VISIBLE_DEVICES、LD_LIBRARY_PATH。
这套清单在不同机器上都能复用,也可以作为 CI 环境检查脚本的基础。
7.2 推理基准脚本开发建议
开发 AgentX 推理基准脚本时,不要一上来就跑完整智能体链路。先做单模型最小验证,再逐步增加复杂度。推荐的迭代路径:
- 只测试单个模型前向推理的延迟和显存。
- 加入多轮对话模拟,观察 KV Cache 显存变化。
- 加入工具调用模拟,在请求之间插入人为延迟,观察 GPU 利用率和调度恢复能力。
- 加入多路并发,测试显存申请、释放和框架线程安全。
- 最后组合成完整的 AgentX 链路,记录端到端指标。
每一步都要保留日志和指标记录,方便在出现性能回退时快速定位是哪一层引入的问题。
7.3 生产环境必须额外处理的环节
AgentX 推理基准跑通后,进入生产环境前还要补齐这些工程能力:
| 工程项 | 推荐做法 |
|---|---|
| 配置外置化 | 模型路径、显存上限、并发数、超时时间都用环境变量或配置中心管理 |
| 日志结构化 | 记录请求 ID、模型名、CUDA 设备、延迟、显存、错误类型 |
| 监控报警 | 订阅 GPU 利用率、显存占用、延迟 P95、OOM 次数 |
| 回滚机制 | 保留上一版本镜像,模型层失败时能快速切换 |
| 异常处理 | 捕获 CUDA OOM、设备丢失、驱动异常,并给出降级策略 |
| 资源隔离 | 多个服务共享 GPU 时,设置显存限制或使用 MPS、时间片调度 |
智能体推理的并发模型比传统推理更复杂,不能只靠单个模型服务的水平扩容。需要评估在同一 GPU 上部署多个模型服务,还是为不同模型分配独立 GPU,再根据延迟和吞吐目标决定。
7.4 未来的学习路径
想深入理解 CUDA 在智能体推理中的作用,可以按下面路径学习:
- 掌握 CUDA 编程基础:线程层次、内存模型、Kernel 启动方式。
- 理解 SM、Block、Grid 的含义:这关系到算子如何映射到硬件执行单元。
- 学习常用加速库:cuBLAS、cuDNN、TensorRT 的使用场景。
- 掌握性能分析工具:使用 ncu 找算子热点,使用 Nsight Systems 看时间线。
- 尝试推理引擎集成:把模型导出为 TensorRT 或 ONNX,再接入智能体框架。
- 了解多后端抽象:研究 PyTorch 的设备抽象机制,理解同一份模型代码如何在不同后端运行。
对大多数智能体开发者来说,不需要达到 CUDA 内核优化专家的水平,但理解驱动、Toolkit、框架、容器之间的协作关系,能显著减少部署和排错时间。这也是 AgentX 推理基准这类系统从“能跑”走向“稳定运行”的关键基础。