当前位置: 首页 > article >正文

AMDGPU 基于DRM SVM框架的新SVM功能实现 :attr_range 与 svm_range 的对应关系分析

AMD 正在使用 drm svm框架重构SVM的实现看来drm svm框架要进入大范围应用了。下面是在kernel社区上由AMD的开发人员提交的POC 验证版本的patches的技术方案实现。这里快速总结了实现以飨读者。因是POC版本设计可能会变动读者们慎重使用。本文仅用来跟踪前沿驱动技术的迭代发展现状。1. 结论amdgpu_svm_attr_range属性层与amdgpu_svm_range映射层不是一一对应的而是N:M 的解耦关系。两者有不同的拆分标准、不同的粒度、不同的生命周期通过amdgpu_svm_range_apply_attr_change()桥接。2. 两层架构概览┌─────────────────────────────────────────────────────────────────┐ │ 用户空间 ioctl │ │ amdgpu_svm_attr_set(start, size, attrs) │ └────────────────────────────┬────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 属性层 (Attribute Layer) │ │ │ │ amdgpu_svm_attr_range: 存储在 attr_tree-tree (interval tree) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ range A │ │ range B │ │ range C │ ← 按属性边界拆分 │ │ │flagsRW │ │flagsRO │ │flagsRW │ │ │ │accessEN │ │accessEN │ │accessNO │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ 职责记录用户设置的属性元数据纯数据无 GPU 映射状态 │ └────────────────────────────┬────────────────────────────────────┘ │ attr_change → trigger ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 映射层 (Mapping Layer) │ │ │ │ amdgpu_svm_range (wraps drm_gpusvm_range): │ │ 存储在 drm_gpusvm_notifier 内的 interval tree │ │ ┌────┐┌────┐┌────┐┌────┐┌────┐┌────┐┌────┐┌────┐ │ │ │ r0 ││ r1 ││ r2 ││ r3 ││ r4 ││ r5 ││ r6 ││ r7 │ ← chunk对齐 │ │ └────┘└────┘└────┘└────┘└────┘└────┘└────┘└────┘ │ │ 职责持有实际 GPU 页表映射、DMA 状态、pages │ └─────────────────────────────────────────────────────────────────┘3. 两层对比维度amdgpu_svm_attr_range(属性层)amdgpu_svm_range/drm_gpusvm_range(映射层)存储位置attr_tree-tree(interval tree)drm_gpusvm_notifier内的 interval tree职责记录用户设置的属性元数据持有实际 GPU 页表映射、DMA 状态、pages拆分依据用户 ioctl 设置的属性边界chunk_size 对齐、VMA 边界、notifier 边界创建时机amdgpu_svm_attr_set_range()— ioctl 驱动drm_gpusvm_range_find_or_insert()— fault/map 驱动持有内容preferred_loc,flags,access,granularitygpu_mapped,pte_flags, pages, DMA mapping粒度任意大如用户对 1GB 区间设置属性 → 一个 attr_range较小受 chunk_sizes (4K/64K/2M)、VMA、notifier 约束生命周期由用户 ioctl 创建attr_clear_pages或进程退出时销毁由 fault/map 创建mmu_notifier invalidate 时可回收4. 拆分标准的差异4.1 attr_range 的拆分属性边界驱动amdgpu_svm_attr_set_existing()在用户对一个已有 attr_range 的子区间设置新属性时会 split 出 left/right 残留段初始状态: attr_range: [ A (flagsRW, accessENABLE) ] 0x1000 0x5000 用户 ioctl: 设置 [0x2000, 0x3000] flagsRO 拆分后: attr_range: [ A (RW) ][ B (RO) ][ A (RW) ] 0x1000 0x1FFF 0x2000 0x3000 0x3001 0x5000关键代码amdgpu_svm_attr_set_existing/* split head */if(startrange_start){leftattr_alloc_range(range_start,start-1,old_attrs);}/* split tail */if(lastrange_last){rightattr_alloc_range(last1,range_last,old_attrs);}4.2 svm_range 的拆分硬件约束驱动drm_gpusvm_range_chunk_size()根据以下约束确定每个 svm_range 的大小for(;igpusvm-num_chunks;i){startALIGN_DOWN(fault_addr,gpusvm-chunk_sizes[i]);endALIGN(fault_addr1,gpusvm-chunk_sizes[i]);if(startvas-vm_startendvas-vm_end// VMA 边界startdrm_gpusvm_notifier_start(notifier)// notifier 边界enddrm_gpusvm_notifier_end(notifier)startgpuva_startendgpuva_end)// GPUVA 边界break;}约束包括chunk_sizes 对齐预定义的 2 的幂数组如 2M, 64K, 4K从大到小尝试VMA 边界不能跨越 CPU VMAnotifier 边界不能跨越 mmu_interval_notifier已有 range 边界不能与已存在的 svm_range 重叠5. N:M 对应关系详解5.1 一个 attr_range 跨多个 svm_range1:N这是最常见的情况。用户通过 ioctl 设置大范围属性产生一个大的 attr_range而 GPU 映射时按 chunk_size 对齐创建多个小的 svm_rangeattr_range: [ 0x1000 - 0x10000 (accessenable) ] svm_ranges: [--64K--][--64K--][--64K--][--64K--][--64K--]... (chunk-aligned) 由 drm_gpusvm_range_find_or_insert() 逐个创建调用路径amdgpu_svm_attr_apply_change() → amdgpu_svm_range_map_interval() → amdgpu_svm_range_map() → while (addr end): drm_gpusvm_range_find_or_insert() ← 每次创建/复用一个 chunk 对齐的 svm_range drm_gpusvm_range_get_pages() amdgpu_svm_range_update_gpu_range()5.2 一个 svm_range 跨多个 attr_rangeM:1设计上会处理如果一个 64K 的 svm_range 恰好覆盖了两个不同属性的 attr_range 区域restore 路径中会按 attr 边界分段处理attr_ranges: [ A (RW) ][ B (RO) ] 0x1000 0x17FF 0x1800 0x1FFF svm_range: [ 64K ] 0x1000 0x1FFFamdgpu_svm_range_map_attr_ranges()通过amdgpu_svm_attr_lookup_page_locked()逐段查询属性按 attr 边界分段映射// amdgpu_svm_range_map_attr_ranges()while(cursorlast_page){// 查询当前页的属性及属性范围的结束位置mutex_lock(attr_tree-lock);amdgpu_svm_attr_lookup_page_locked(attr_tree,cursor,attrs,seg_last);mutex_unlock(attr_tree-lock);seg_lastmin(seg_last,last_page);if(range_has_access(attrs.access)){retamdgpu_svm_range_map_interval(svm,cursor,seg_last,attrs);}cursorseg_last1;}5.3 attr_range 空洞默认属性区域在 attr_tree 中不存在 attr_range 的区域使用默认属性。amdgpu_svm_attr_lookup_page_locked()在查询空洞时返回默认属性// 查询命中空洞时attr_set_default(attr_tree-svm,attrs);*range_lastULONG_MAX;// 查找下一个 attr_range 的起始位置来确定空洞的结束nodeinterval_tree_iter_first(attr_tree-tree,page1,ULONG_MAX);if(node){rangecontainer_of(node,structamdgpu_svm_attr_range,it_node);if(range-it_node.startpage)*range_lastrange-it_node.start-1;}6. 桥接机制属性变更如何传递到映射层6.1 完整调用链amdgpu_svm_attr_set() ← 用户 ioctl 入口 │ ├─ 验证 VMA 检查 │ └→ amdgpu_svm_attr_set_range() ← 遍历 [start, last]按 attr 段处理 │ │ while (cursor last): │ ┌─ cursor 命中已有 attr_range? │ │ YES → amdgpu_svm_attr_set_existing() ← 可能 split left/right │ │ NO → amdgpu_svm_attr_set_hole() ← 空洞区域创建新 range │ │ │ └→ 产生 attr_set_ctx { start, last, trigger, prev_attrs, new_attrs } │ └→ amdgpu_svm_attr_apply_change() ← 桥接属性层 → 映射层 │ │ 根据 trigger 类型决定操作 │ ├─ ACCESS_CHANGE new_access: │ → amdgpu_svm_range_map_interval() ← remap GPU 页表 │ ├─ PTE_FLAG_CHANGE / MAPPING_FLAG_CHANGE: │ → amdgpu_svm_range_map_interval() ← remap GPU 页表 │ └─ LOCATION_CHANGE: → amdgpu_svm_range_rebuild_locked() ← destroy recreate svm_ranges │ ├─ amdgpu_svm_range_remove_overlaps() ← 删除旧 svm_ranges └─ amdgpu_svm_range_map_attr_ranges() ← 按 attr 边界重建6.2 trigger 类型与映射层操作的对应trigger 类型映射层操作原因ATTR_TRIGGER_ACCESS_CHANGE(enable)map_interval→ remap需要建立新的 GPU 映射ATTR_TRIGGER_ACCESS_CHANGE(disable)无操作 (align with KFD)TODO: 应 unmapATTR_TRIGGER_PTE_FLAG_CHANGEmap_interval→ remapPTE flags 变了需要更新页表ATTR_TRIGGER_MAPPING_FLAG_CHANGEmap_interval→ remap映射策略变了需要更新ATTR_TRIGGER_LOCATION_CHANGErebuild_locked→ destroy recreatemigrate_devmemflag 是不可变的必须重建 rangeATTR_TRIGGER_GRANULARITY_CHANGE无操作粒度变化只影响后续 range 创建ATTR_TRIGGER_ATTR_ONLY无操作无实质变化6.3 LOCATION_CHANGE 需要 rebuild 的原因drm_gpusvm_range的migrate_devmemflag 在创建时就确定了来自gpusvm_ctx.devmem_possible之后不可变。如果用户改变了preferred_loc/prefetch_loc旧的 svm_range 仍然带着过时的 flagmigration 不会发生。因此必须删除旧的 svm_rangesamdgpu_svm_range_remove_overlaps重新创建amdgpu_svm_range_map_attr_ranges新 range 会从当前 attr 读取最新的devmem_possible7. svm_range 不直接存储属性amdgpu_svm_range只缓存属性的结果不存储属性本身structamdgpu_svm_range{structdrm_gpusvm_rangebase;bool gpu_mapped;// 是否已映射到 GPUuint64_tpte_flags;// 当前 GPU PTE flags属性的结果uint32_tattr_flags;// 当前属性 flags 的快照// ... 没有 preferred_loc, access 等属性字段};当 svm_range 需要 restore如 eviction 后恢复映射时会回查 attr_tree获取最新属性// amdgpu_svm_range_map_attr_ranges() — restore 路径amdgpu_svm_attr_lookup_page_locked(attr_tree,cursor,attrs,seg_last);// 用查到的 attrs 重新映射amdgpu_svm_range_map_interval(svm,cursor,seg_last,attrs);这确保了即使属性在 eviction 期间被修改restore 时也能使用最新的属性。8. 锁的协调两层使用不同的锁且有特定的获取顺序amdgpu_svm_attr_set_range() 中的锁序 mutex_lock(attr_tree-lock); ← 属性层锁 // 修改 attr_tree mutex_unlock(attr_tree-lock); down_write(svm-svm_lock); ← 映射层锁 amdgpu_svm_attr_apply_change(); // 操作 svm_ranges up_write(svm-svm_lock);不能同时持有两把锁因为amdgpu_svm_range_map_interval()内部需要获取mmap_read_lock如果持有attr_tree-lock可能导致死锁。因此设计上先释放 attr 锁再获取 svm 锁。9. 图示总结用户视角 (ioctl): [ 设置 accessENABLE, flagsRO ] start_page last_page 属性层 (attr_tree): [hole][ attr_A ][ hole ][ attr_B ][hole][attr_C] ↑ default attrs ↑ default ↑ default 各段按属性边界划分与 ioctl 历史相关 映射层 (gpusvm): [r0][r1] [r2][r3][r4] [r5][r6][r7][r8] [r9][r10] ↑ 按 chunk_size 对齐受 VMA/notifier 边界约束 各段独立持有 GPU 页表映射状态 对应关系: N : M 无固定对应通过 attr_lookup 动态查询桥接概念说明attr_range“这段 VA 有什么属性”面向用户ioctl 驱动纯元数据svm_range“这段 VA 有什么 GPU 映射”面向硬件fault/map 驱动持有页表状态对应关系 N:M属性边界 ≠ 映射边界两者独立拆分桥接 trigger → range remap/rebuildattr 层通知 range 层属性变了请更新映射这种解耦设计的好处是属性管理用户策略和 GPU 映射管理硬件约束各自独立演进互不干扰。10. 复杂性代价分析N:M 解耦设计引入了明显的复杂性需要客观评估其代价与收益。10.1 引入的具体复杂性(1) 锁序窗口期与 retry 机制因为两层各有独立的锁amdgpu_svm_attr_set_range()不得不采用释放 attr 锁 → 获取 svm 锁的模式mutex_lock(attr_tree-lock);// 修改 attr_tree属性已变mutex_unlock(attr_tree-lock);← 窗口期属性已改映射未更新down_write(svm-svm_lock);amdgpu_svm_attr_apply_change();// 更新映射up_write(svm-svm_lock);在这个窗口期内如果另一个线程读取 attr 并触发 restore可能看到属性与映射不一致的状态。代码中的-EAGAINretry 机制正是为了应对这种竞争// amdgpu_svm_attr_set() 中retry:ramdgpu_svm_attr_set_range(...);if(r-EAGAIN){amdgpu_svm_range_flush(svm);cond_resched();gotoretry;}如果是单层设计只需一把锁保护原子操作不需要 retry。(2) restore 路径必须逐段查属性因为svm_range不存储完整属性每次 restore 都要调用amdgpu_svm_attr_lookup_page_locked()逐段查询 attr_tree// restore 路径 — 每个 svm_range 都要回查 attr_treewhile(cursorlast_page){mutex_lock(attr_tree-lock);amdgpu_svm_attr_lookup_page_locked(attr_tree,cursor,attrs,seg_last);mutex_unlock(attr_tree-lock);amdgpu_svm_range_map_interval(svm,cursor,seg_last,attrs);cursorseg_last1;}如果是 1:1 对应svm_range直接内嵌属性即可restore 零查询开销。(3) LOCATION_CHANGE 的 destroy recreate 开销因为drm_gpusvm_range的migrate_devmemflag 在创建时不可变location 属性变更时必须销毁再重建所有重叠的 svm_range。这意味着丢弃已有的 GPU 映射和 DMA 状态重新走一遍完整的 map 流程。如果属性直接存在 svm_range 上且 flag 可变只需修改 flag 重新 migrate无需 destroy但这受限于drm_gpusvm框架设计。(4) 两棵独立 interval tree 的维护负担内存开销两棵树各自维护节点代码复杂度边界不对齐时的交叉查询逻辑容易出错调试难度排查问题需要同时 dump 两棵树的状态才能理清全貌10.2 为什么仍然采用这种设计核心原因是两层受不同的外部约束无法统一约束来源attr_rangesvm_range边界由谁决定用户 ioctl任意地址范围drm_gpusvm框架chunk 对齐 VMA notifier生命周期持久存在直到用户清除或进程退出可能被 mmu_notifier 随时回收再重建可控性amdgpu 驱动完全控制drm_gpusvm是 DRM 公共框架xe、amdgpu 共用不能改其 range 结构关键限制drm_gpusvm_range是 DRM 子系统的公共框架它的 range 拆分逻辑和生命周期不能为 amdgpu 的属性需求定制。所以 amdgpu 只能在外面再加一层属性管理。10.3 如果要简化的方向理论上如果drm_gpusvm_range能支持以下能力就可以去掉 attr_tree只维护一棵树需要的框架改动当前限制简化效果range 内嵌驱动私有属性drm_gpusvm_range无属性字段无需外部 attr_treemigrate_devmem可变 / 延迟决定创建时确定不可变无需 destroy recreaterange 拆分时感知属性边界chunk_size 纯硬件对齐减少 N:M 不对齐情况但这需要修改 DRM 公共框架影响面涉及 xe 等其他驱动短期内不现实。10.4 小结复杂性代价 设计收益 ───────────── ───────── 锁序窗口 retry 机制 属性层与映射层独立演进 restore 逐段查属性开销 svm_range 被回收后属性仍然保留 LOCATION_CHANGE destroyrecreate 不侵入 drm_gpusvm 公共框架 两棵 interval tree 维护成本 适配 KFD 属性语义兼容用户空间 API总结复杂性是真实的代价根本原因是 amdgpu 的属性管理需求与drm_gpusvm公共框架的 range 管理模型不匹配被迫用两层解耦来适配。如果未来drm_gpusvm框架能扩展属性支持能力这层复杂性可以消除。

相关文章:

AMDGPU 基于DRM SVM框架的新SVM功能实现 :attr_range 与 svm_range 的对应关系分析

AMD 正在使用 drm svm框架重构SVM的实现,看来drm svm框架要进入大范围应用了。下面是在kernel社区上由AMD的开发人员提交的POC 验证版本的patches的技术方案实现。这里快速总结了实现,以飨读者。 因是POC版本,设计可能会变动,读者…...

gitoxide日志系统:Rust实现的Git操作日志分析

gitoxide日志系统:Rust实现的Git操作日志分析 【免费下载链接】gitoxide An idiomatic, lean, fast & safe pure Rust implementation of Git 项目地址: https://gitcode.com/GitHub_Trending/gi/gitoxide 在日常的Git使用中,我们经常需要查看…...

商业逻辑和产品本质的庖丁解牛

“商业逻辑”与“产品本质”,常被混淆为“怎么赚钱”和“功能列表”。 但本质上: 商业逻辑是价值交换的闭环:谁为谁解决了什么问题,谁为此付费,利润从何而来,如何持续。产品本质是需求的具象化解决方案&…...

数码管驱动原理与工程实现指南

数码管驱动原理与工程实现指南1. 数码管基础认知1.1 数码管分类体系数码管(LED Segment Display)作为经典的显示器件,其分类维度主要包括:字段结构:七段管:包含a-g七个基本段八段管:增加小数点h(DP)段米字管&#xff1…...

国风AI绘画从零开始:Guohua Diffusion部署与使用教程,生成专属水墨作品

国风AI绘画从零开始:Guohua Diffusion部署与使用教程,生成专属水墨作品 想亲手创作一幅意境悠远的水墨山水,或是描绘一幅灵动飘逸的工笔花鸟吗?过去,这需要多年的绘画功底。现在,借助AI的力量,…...

SUPER COLORIZER模型压缩技术:使用TensorRT加速推理并减少显存占用

SUPER COLORIZER模型压缩技术:使用TensorRT加速推理并减少显存占用 你是不是也遇到过这种情况?一个效果很棒的图像上色模型,比如SUPER COLORIZER,跑起来效果惊艳,但推理速度慢得像蜗牛,显存占用还高得吓人…...

突破性能瓶颈:MuJoCo大规模仿真云服务架构实战指南

突破性能瓶颈:MuJoCo大规模仿真云服务架构实战指南 【免费下载链接】mujoco Multi-Joint dynamics with Contact. A general purpose physics simulator. 项目地址: https://gitcode.com/GitHub_Trending/mu/mujoco MuJoCo(多关节接触动力学&…...

上位机与下位机通信协议详解:RS232 vs RS485的优缺点及实际应用案例

上位机与下位机通信协议详解:RS232 vs RS485的优缺点及实际应用案例 在工业自动化系统中,上位机与下位机的高效通信是确保整个系统稳定运行的关键。作为开发者,我们经常需要在RS232和RS485这两种经典串行通信协议之间做出选择。这两种协议各有…...

Wan2.2-I2V-A14B prompt工程实战:如何编写提示词控制视频运动风格

Wan2.2-I2V-A14B prompt工程实战:如何编写提示词控制视频运动风格 1. 引言 想让AI生成的视频动起来更自然、更有电影感吗?Wan2.2-I2V-A14B模型可以帮你实现这个目标,但关键在于如何写好提示词。就像导演给演员说戏一样,好的提示…...

【PyCharm+tracemalloc+objgraph三剑合璧】:从泄漏发生到热修复仅需97秒——一线大厂SRE团队内部手册首次公开

第一章:PyCharmtracemallocobjgraph三剑合璧:内存泄漏修复范式总览在 Python 应用长期运行场景中,内存泄漏常表现为进程 RSS 持续攀升、GC 频率异常升高或对象数量无衰减增长。单靠 psutil 或 top 仅能发现症状,无法定位根源。本范…...

钓鱼即服务韧性机制与执法行动局限性实证研究

摘要 随着网络犯罪生态系统的产业化演进,“钓鱼即服务”(Phishing-as-a-Service, PhaaS)已成为威胁全球网络安全的核心形态。本文以2026年3月针对"Tycoon 2FA"平台的国际联合执法行动为实证案例,深入剖析了该平台在遭受…...

【TRO 26-cv-924】Canada Goose携手GBC重磅维权!超40名跨境卖家被诉,即将缺席审判!

导语:服饰、箱包类卖家紧急预警! 国际知名羽绒服品牌Canada Goose Inc.(加拿大鹅)发起新一轮商标维权风暴!案件号【26-cv-924】已在美国伊利诺伊州北区联邦法院正式立案。本次维权直指商标侵权与仿冒,超40家…...

Linux磁盘调度算法终极指南:如何选择最佳IO性能优化方案

Linux磁盘调度算法终极指南:如何选择最佳IO性能优化方案 【免费下载链接】linux-tutorial :penguin: Linux教程,主要内容:Linux 命令、Linux 系统运维、软件运维、精选常用Shell脚本 项目地址: https://gitcode.com/GitHub_Trending/lin/li…...

电视投屏的终极解决方案:TVBoxOSC如何让手机内容秒变大屏体验

电视投屏的终极解决方案:TVBoxOSC如何让手机内容秒变大屏体验 【免费下载链接】TVBoxOSC TVBoxOSC - 一个基于第三方项目的代码库,用于电视盒子的控制和管理。 项目地址: https://gitcode.com/GitHub_Trending/tv/TVBoxOSC 你是否曾羡慕朋友家的智…...

语析Yuxi-Know:构建企业级智能知识管理系统的技术架构与实践

语析Yuxi-Know:构建企业级智能知识管理系统的技术架构与实践 【免费下载链接】Yuxi-Know 基于大模型 RAG 知识库与知识图谱的问答平台。Llamaindex VueJS Flask Neo4j。大模型适配 OpenAI、国内主流大模型平台的模型调用、本地 vllm 部署。 项目地址: https://…...

STM32F1轻量USB复合设备库:HID+MIDI+MSC一体化实现

1. 项目概述USBComposite for STM32F1 是一个面向 STM32F1 系列微控制器(基于 ARM Cortex-M3 内核)的轻量级、可裁剪式 USB 复合设备固件库。其核心目标是在资源受限的 F1 平台(典型 Flash ≤ 64KB,SRAM ≤ 20KB)上&am…...

新手避坑指南:用C语言写数字滤波器时最容易犯的3个错误(含调试技巧)

C语言数字滤波器实战:新手必知的3个致命陷阱与高效调试方案 当你在深夜调试一段滤波器代码时,显示器上那些看似合理的输出数据,可能正在掩盖着危险的编程陷阱。我曾见过太多初学者在实现C语言数字滤波器时,反复掉入相同的坑里——…...

Qwen3.5-4B-Claude-Opus部署教程:llama-server内核+FastAPI外层封装架构解析

Qwen3.5-4B-Claude-Opus部署教程:llama-server内核FastAPI外层封装架构解析 1. 模型概述 Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF是一个基于Qwen3.5-4B的推理蒸馏模型,特别强化了结构化分析、分步骤回答、代码与逻辑类问题的处理能力。该…...

终极指南:如何完美使用Decky Loader打造个性化Steam Deck

终极指南:如何完美使用Decky Loader打造个性化Steam Deck 【免费下载链接】decky-loader A plugin loader for the Steam Deck. 项目地址: https://gitcode.com/gh_mirrors/de/decky-loader 想要让你的Steam Deck游戏体验更上一层楼吗?Decky Load…...

如何通过MiroFish构建企业级智能体应用:从核心引擎到场景落地

如何通过MiroFish构建企业级智能体应用:从核心引擎到场景落地 【免费下载链接】MiroFish A Simple and Universal Swarm Intelligence Engine, Predicting Anything. 简洁通用的群体智能引擎,预测万物 项目地址: https://gitcode.com/GitHub_Trending/…...

StructBERT情感分类-中文-通用-base实战教程:Prometheus+Grafana监控GPU利用率

StructBERT情感分类-中文-通用-base实战教程:PrometheusGrafana监控GPU利用率 1. 模型介绍与环境准备 StructBERT情感分类模型是基于阿里达摩院StructBERT预训练模型微调的中文情感分析模型,专门用于中文文本的情感三分类任务。该模型能够准确识别文本…...

如何利用gs-quant构建专业量化金融分析系统

如何利用gs-quant构建专业量化金融分析系统 【免费下载链接】gs-quant 用于量化金融的Python工具包。 项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant 在现代金融市场中,量化分析已成为投资决策的核心驱动力。随着市场复杂度提升,金…...

STM32新手必看:如何用I2C驱动128x64 OLED屏幕(附完整代码)

STM32新手必看:如何用I2C驱动128x64 OLED屏幕(附完整代码) 在嵌入式开发中,OLED屏幕因其高对比度、低功耗和快速响应等优势,成为许多项目的首选显示方案。对于STM32初学者来说,掌握I2C接口驱动OLED屏幕是一…...

打造Matlab人脸考勤系统(GUI):深度学习的奇妙之旅

matlab人脸考勤系统(GUI),深度学习方法 源码详细注释 提供详细三千字帮助说明文档 GUI里的人脸识别算法:CNN,人脸检测方法VJ算法,可实现静态图像/实时图像的识别在当今数字化时代,考勤系统不断升级,基于深度学习的人脸…...

HunyuanVideo-Foley开源大模型部署:24G显存专用调度策略深度解读

HunyuanVideo-Foley开源大模型部署:24G显存专用调度策略深度解读 1. 镜像概述与核心价值 HunyuanVideo-Foley 是一款集视频生成与音效生成于一体的多模态大模型,本镜像专为RTX 4090D 24GB显存环境深度优化。相比通用部署方案,本镜像通过以下…...

Verge:轻量级视口检测与DOM操作工具库全解析

Verge:轻量级视口检测与DOM操作工具库全解析 【免费下载链接】verge get viewport dimensions...detect elements in the viewport...trust in 项目地址: https://gitcode.com/gh_mirrors/ver/verge 在现代前端开发中,视口检测与DOM操作是构建响…...

1Drake:面向机器人开发的模型设计与验证框架

1Drake:面向机器人开发的模型设计与验证框架 【免费下载链接】drake Model-based design and verification for robotics. 项目地址: https://gitcode.com/gh_mirrors/dr/drake 核心价值解析 理解Drake的核心定位 Drake是一个开源的机器人仿真与控制框架&a…...

CY7C68013芯片开发指南:用CyAPI库快速实现USB设备枚举(附VS2022工程模板)

CY7C68013芯片开发实战:从CyAPI环境搭建到设备枚举全流程解析 在物联网设备开发领域,USB通信始终扮演着关键角色。CY7C68013作为Cypress经典的EZ-USB FX2系列芯片,凭借其稳定的性能和灵活的配置选项,依然是众多硬件开发者的首选。…...

AlphaGenome:如何用AI揭示DNA序列的隐藏功能

AlphaGenome:如何用AI揭示DNA序列的隐藏功能 【免费下载链接】alphagenome-all-folds 项目地址: https://ai.gitcode.com/hf_mirrors/google/alphagenome-all-folds 导语 DeepMind推出的AlphaGenome模型通过统一的AI框架实现了对DNA序列功能的多模态预测&a…...

9MW 双馈风力发电机(DFIG)Simulink 模型设计与控制策略探索

9MW双馈风力发电机simulink设计模型(DFIG)控制策略,包括风机模型,网侧和机侧控制,给定风速变化(可自行变风速),背靠背变流器直流侧电压为1150v,电流电压等波形良好&#…...