news 2026/9/13 4:53:26

Teable 的 v2 Core application 层架构:应用服务、投影与跨表副作用编排

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Teable 的 v2 Core application 层架构:应用服务、投影与跨表副作用编排

Teable 的 v2 Core application 层架构:应用服务、投影与跨表副作用编排

【免费下载链接】teable✨ AI Spreadsheet for Business项目地址: https://gitcode.com/GitHub_Trending/te/teable

导读

Teable 在packages/v2/core中落地了一套清晰的分层架构:命令(Command)负责入口,领域模型(Domain)承载业务规则,而介于两者之间的application 层(packages/v2/core/src/application)专门负责"编排"——协调仓储、跨聚合工作流、事务边界与事件发布。本文以该目录下的 ARCHITECTURE.md 为核心骨架,深入剖析应用服务的职责边界、projections/services/两个子目录的组成,并结合TableUpdateFlowFieldCreationSideEffectServiceRecordCreationServiceDeleteByRangeApplicationService等核心实现,说明 Teable 如何在保持领域纯净的同时完成复杂的跨表副作用、实时投影与撤销/重做。读完本文,你将理解 v2 Core 分层设计的约束动机,并能据此定位、扩展或复用 application 层的编排服务。

一、application 层在整个 v2 Core 中的位置

在深入本目录之前,先明确它的上级语境。根据 packages/v2/core/src/ARCHITECTURE.md,v2 Core 的源码根目录分为五大部分:

目录职责
commands/应用命令与处理器(写侧入口)
queries/应用查询与处理器(读侧入口)
application/编排领域行为、协调端口的应用服务
domain/领域模型(聚合、值对象、规格、事件)
ports/端口及默认/内存实现、映射器

同时该文档明确了三条分层规则

  1. 命令处理器可以编排端口与应用服务,但不得调用其他命令处理器,也不得通过ICommandBus重新分发命令;
  2. 共享的写行为应下沉到application/services/中,由多个处理器复用;
  3. 仓储专属的持久化后工作(如 schema 刷新、回填重放、仓储起源的 action-trigger 收集)必须留在仓储的create/update/delete方法内部,应用流程只能消费返回的聚合及其领域事件。

这三条规则直接解释了为什么需要application/这一层:它是"共享编排逻辑"的收容所,避免命令处理器之间互相调用、避免领域模型被基础设施污染。

二、application 层职责:编排而非实现规则

application/ARCHITECTURE.md 用三句话概括了本层定位:

  • 职责一:提供"编排领域行为、协调端口"的应用服务;
  • 职责二:拥有跨聚合工作流、事务与事件发布边界;
  • 职责三(边界红线)不得包含领域规则——领域规则必须委托给领域服务 / 实体 / 访问器(visitor)实现。

理解这条边界的关键在于区分两种代码:

  • 领域规则:例如"双向关联字段(link field)删除后必须同步删除对称字段""新建字段时关联表需要产生何种副作用""字段类型转换的合法性校验"。这些逻辑写在domain/table下的 visitor 与 spec 中,例如FieldCreationSideEffectVisitorFieldDeletionSideEffectVisitor
  • 编排逻辑:例如"先收集副作用 → 逐表在事务中应用变更 → 汇总事件 → 发布事件"。这些正是 application 服务要承担的。

以 FieldCreationSideEffectService.ts 为例,其类注释直接写明:"Application service: coordinates repositories and update flow for cross-table side effects. Domain logic lives in visitors/specs; this class only orchestrates persistence and events."(应用服务协调仓储与更新流程以完成跨表副作用,领域逻辑位于 visitor/spec 中,本类仅编排持久化与事件)。这是整层设计哲学的最直观注脚。

为什么需要这个"编排层"?

从源码可以归纳出三个动机:

  1. 跨聚合一致性:字段创建/删除的副作用会落在"另一张表"(foreign table)上,需要同时更新多张表的元数据,天然属于跨聚合工作流,领域聚合本身无法单独完成;
  2. 事务与事件边界的统一:变更、持久化、事件发布必须被编排到同一个事务作用域,并保证"提交后发布"的时序;
  3. 多处理器复用:同一个工作流(如单条记录创建、按范围删除)会被多个命令处理器调用,抽成共享服务可避免重复实现。

三、子目录导航:projections 与 services

application 目录下有两个子目录,职责边界非常清晰:

子目录职责
projections/投影(Projection)类型与基于 EventHandler 的处理器装饰器别名
services/应用服务实现(仅编排)

顶层还直接放置了若干编排类(如DeleteByRangeApplicationServiceTableUpdateFlowRecordCreationServiceRecordWritePluginRunner等)与对应的测试(.spec.ts),以及本架构说明文件。

3.1 projections/:把领域事件绑定到派生效果

projections/ARCHITECTURE.md 明确了投影的职责:

  • 定义"把领域事件绑定到派生效果"的投影类型;
  • 提供投影事件绑定的装饰器别名;
  • 投影必须是 EventHandler,处理器内部不得做事件类型分支(keep projections as EventHandlers, no event type branching inside handlers)。

其核心文件是 Projection.ts:

import type { IDomainEvent } from '../../domain/shared/DomainEvent'; import type { EventType, IEventHandler } from '../../ports/EventHandler'; import { EventHandler } from '../../ports/EventHandler'; export type IProjection<TEvent extends IDomainEvent = IDomainEvent> = IEventHandler<TEvent>; export const ProjectionHandler = <TEvent extends IDomainEvent>(event: EventType<TEvent>) => EventHandler(event, { role: 'projection' });

可以看到IProjection只是IEventHandler的别名,ProjectionHandler则是EventHandler的薄封装,额外标记了role: 'projection'——这让投影在事件总线上拥有独立的语义身份。投影处理器通过装饰器绑定到特定领域事件类型,例如:

@ProjectionHandler(FieldCreated) @injectable() export class FieldCreatedRealtimeProjection implements IEventHandler<FieldCreated> { ... }

RealtimeProjection.ts是一个标记类型,用于标注"面向实时引擎(realtime engine)"的投影。目录内现有的实时投影包括:

  • TableCreatedRealtimeProjection.ts —— 建表时发布表快照;
  • FieldCreatedRealtimeProjection.ts —— 建字段时发布字段快照(同时通过RealtimeTableSnapshotCache复用表快照,并用realtimeEngine.ensure保证表文档与字段文档存在);
  • FieldDeletedRealtimeProjection.ts —— 删字段时删除字段快照;
  • ViewColumnMetaUpdatedRealtimeProjection.ts —— 字段增删导致视图列元数据变化时更新快照。

投影只负责"事件 → 派生数据"的单向推导,不会回写领域模型,这是它区别于应用服务的关键。以FieldCreatedRealtimeProjection.handle为例,它加载表快照、确保表文档存在、再从快照中取出字段 DTO 写入实时引擎,全程只读消费事件与仓储数据。

3.2 services/:事务化编排的容器

services/ARCHITECTURE.md 给出了更细的职责描述:

  • 实现"协调仓储、schema 更新与事件发布"的应用服务;
  • 围绕领域变更与 spec 提供事务化编排
  • 领域逻辑保留在领域模型/visitor 中;本层只负责接线端口,并为跨表校验提供预加载数据。

同时该文档列出了一批典型的服务及其定位,下面逐一结合源码展开。

四、核心应用服务源码级剖析

4.1 TableUpdateFlow:事务化表更新的统一流水线

TableUpdateFlow.ts 是 application 层最基础的"基座"服务,字段创建/删除副作用服务都依赖它。它的职责正如文档所述:"shared table update workflow (mutate + persist + publish)",即变更 → 持久化 → 发布三步走。

execute方法接收四个要素:执行上下文、更新目标(可直接传Table聚合,也可传tableIdTableUpdateCommand让流程自行解析)、变更函数((table) => Result<TableUpdateResult, DomainError>)、以及可选选项(publishEventsprepare/afterPersist钩子)。

整个流程的关键步骤(对应 TableUpdateFlow.ts):

  1. 解析目标表:若目标只含tableId,则通过TableRepository.findOne加载聚合;
  2. 执行领域变更:调用调用方传入的mutate(table),得到更新后的表与变更 spec(mutateSpec),并拉取表聚合上累积的领域事件(pullDomainEvents);
  3. 判断是否需要物理 schema 修复mayRequirePhysicalSchemaRepair检查mutateSpec是否包含会改变物理结构的 spec——TableAddFieldSpecTableRemoveFieldSpecTableDuplicateFieldSpecTableUpdateFieldDbFieldNameSpecTableUpdateFieldConstraintsSpecUpdateLinkConfigSpecUpdateLinkRelationshipSpecRemoveSymmetricLinkFieldSpec,以及"发生类型转换"的TableUpdateFieldTypeSpec。若需要,则先行beginTableSchemaOperation(因为在"元数据/数据分库"场景下,DDL 可能先于元数据事务提交被看到,需要 schema 操作生命周期管理);
  4. 双事务阶段:外层withTransaction(..., { scope: 'meta' })中先执行prepare钩子,然后在数据阶段({ scope: 'data' })内调用tableSchemaRepository.update落物理 schema、执行afterPersist钩子,最后flushTableUpdateTransactionScope
  5. 失败恢复:事务失败时,根据是否已持久化元数据,选择failRecoverableTableSchemaOperation(可恢复失败)或completeTableSchemaOperation(记录不可修复失败),并保留原始错误返回;
  6. 提交后收尾:通过registerAfterCommit(context, finalizeReady)注册提交后完成 schema 操作;若外层事务回滚,则registerAfterRollback记录失败状态,且"不使表不可用";
  7. 事件版本回填与发布attachPersistedEventVersions将仓储返回的字段/视图版本变化(fieldVersionChanges/viewVersionChanges)回填到FieldUpdatedFieldOptionsAddedViewColumnMetaUpdated事件上(按字段/视图 ID 排队、逐事件消费);随后经eventBus.publishMany发布领域事件与持久化后事件(postPersistEvents)。

这个服务是理解"Teable 如何在分库(meta/data split)场景下保证 DDL 与元数据一致性"的最佳入口:schema 操作生命周期 + 双层事务 + 提交后收尾三者配合,正是ARCHITECTURE.md所说"跨聚合工作流、事务与事件发布边界"的具体实现。

4.2 FieldCreationSideEffectService:建字段的跨表副作用

当用户新建一个关联字段(link 字段)时,往往会触发对端表的结构变化。FieldCreationSideEffectService负责"validate cross-table field dependencies (via visitors) and apply side effects after field creation"。

其流程(对应 FieldCreationSideEffectService.ts):

  1. 维护一个tableState映射(foreign table id → Table 聚合),并把当前表也放入其中;
  2. 调用领域侧的FieldCreationSideEffectVisitor.collect收集副作用 spec——这是领域规则所在,应用服务不参与判断
  3. preview阶段:逐条在内存中对目标表执行mutateSpec.mutate(foreignTable),产出"预览后的表状态",用于调用方预先校验(如数据安全限制检查);
  4. execute阶段:逐条副作用调用tableUpdateFlow.execute以事务方式落库,并以publishEvents: false抑制逐表事件发布,最后统一返回{ events, tableState }交由调用方决定何时发布。

一个关键细节:executetableUpdateFlow.execute的 mutate 回调会把 spec 包成TableUpdateResult.create(updated, sideEffect.mutateSpec),即"变更结果与变更 spec 一起交给流程",从而让TableUpdateFlow能够判断是否触发物理 schema 修复。

4.3 FieldDeletionSideEffectService:删字段的对称清理

删除字段比创建更危险:对于 link 字段,必须同步删除对端表的对称字段;在字段被软删除后,还要保证"孤儿 link/lookup 字段仍然可删"。FieldDeletionSideEffectService的实现与创建流程对称(对应 FieldDeletionSideEffectService.ts):

  1. FieldDeletionSideEffectVisitor.collect收集删除副作用;
  2. 逐副作用在事务中应用,同样以publishEvents: false聚合事件;
  3. 若副作用 spec 是TableRemoveFieldSpec,则记录appliedDeletions(被删字段、变更前表、变更后表),供调用方做撤销/重做快照或后续元数据清理。

注意删除流程没有 preview 阶段,且输入只包含tablefieldsforeignTables三项,这是因为删除副作用的"可预览性"需求低于创建(创建需要先经过数据安全限制等检查)。

4.4 ForeignTableLoaderService:一次加载、集中校验

跨表副作用的前提是"先把对端表加载出来"。ForeignTableLoaderService实现了 "load foreign tables once and validate missing references"(对应 ForeignTableLoaderService.ts):

  • load(context, { baseId, references, allowMissing }):按baseId对引用分组(无 baseId 的归入__any__),用TableAggregate.specs(baseId).byIds(...)批量查询,最后校验缺失引用——默认情况下任一 foreign table 缺失即返回notFound错误并携带missingForeignTableIds明细;
  • allowMissing: true是专门给"删字段流程"用的:当对端表已被软删除或彻底移除后,孤儿 link/lookup 字段必须仍可删除,此时缺失引用会被跳过而不是失败(该选项在源码注释中有明确说明);
  • loadForLinkTitleFill:针对typecast场景,通过内部MissingLinkTitleForeignTableCollector(一个ICellValueSpecVisitor)从单元格值 spec 中收集"需要按标题解析链接目标"的引用,再去加载对应表,用于记录写入时填充 link 标题。

此外还提供了NullForeignTableLoaderService(空实现,用于不依赖外表的默认场景),这种"接口 + 可替换实现"的组合体现了依赖注入端口(port)风格。

4.5 RecordCreationService:单条记录创建的共享工作流

RecordCreationService是"shared single-record creation workflow reused by multiple handlers",即被"创建单条记录 / 表单提交(submit)/ 复制记录(duplicate)"三类入口复用的统一创建流程(对应 RecordCreationService.ts)。其编排链路非常完整,几乎串联了 application 层的所有关键服务:

  1. FieldKeyResolverService.resolveFieldKeys:把输入按fieldKeyType(字段 ID 或字段名)解析为字段 ID → 值;
  2. recordWritePluginRunner.prepare(...).guard():执行记录写插件的 prepare/guard 阶段(详见下文);
  3. recordWriteSideEffectService.execute:处理写记录的跨表副作用(例如 select 选项的按需创建),得到"可用于创建的表状态";
  4. recordWriteUndoRedoPlanService.captureSelectOptionSideEffects:为 select 选项副作用捕获撤销/重做计划;
  5. 领域调用tableForCreate.createRecord(resolvedFieldValues, { typecast, source })生成记录与 mutate spec;若 spec 需要解析(如按标题写链接),则recordMutationSpecResolver.resolveAndReplace替换为可落库的 spec;
  6. 事务内:先(如有必要)执行tableUpdateFlow.execute落表变更,再pluginExecution.beforePersist,随后tableRecordRepository.insert插入记录(typecast 时携带fillLinkTitlesfillLinkTitleForeignTables);
  7. 事务外:recordChangedValueDecoratorService装饰变更字段值、合并计算字段变化(computedChanges)后构造RecordCreated事件,eventBus.publishMany发布;
  8. requireStoredRecordSnapshot校验持久化快照,undoRedoStackService.appendRecordCreate追加撤销/重做栈(包含 select 选项副作用的 undo/redo 命令);
  9. 最后pluginExecution.afterCommit(),并返回{ record, events, fieldKeyMapping, computedChanges }

其中fieldKeyMapping的意义在于:当请求以字段名写入时,响应需要用字段名回指字段 ID,方便调用方做键映射。这个服务完整展示了"应用服务 = 编排多个端口/子服务 + 领域模型只出规则与事件"的范式。

4.6 RecordWritePluginRunner:记录写插件的四阶段编排

RecordWritePluginRunner.ts 实现了文档所说的 "run typed record-write plugins across prepare/guard/beforePersist/afterCommit phases"。从源码可见其编排细节:

  • 插件阶段supports → prepare → scope → guard → beforePersist → afterCommit,其中supports决定插件是否参与本次操作;
  • enforce 分组enforceOrderpre/post(默认居中)插件分入三组,保证执行顺序确定(createEnforceGroups);
  • 上下文处理sanitizeRecordWritePluginContext通过table.clone(tableMapper)对传入的表做克隆,避免插件污染主聚合;withTransactionBoundContext在事务内阶段把isTransactionBound置为 true;
  • 可观测性:每个阶段都会创建带插件名与阶段名的 trace span(createRecordWritePluginTraceAttributes,含TeableSpanAttributes.OPERATIONPLUGIN_PHASE等属性)。

它支撑了 Teable 的"表数据安全限制"(TableDataSafetyLimitRecordWritePlugin)与"表字段数限制"(TableFieldLimitFieldOperationPlugin)等能力,这些插件同样位于services/下,印证了"应用服务/插件编排"在该层的密度。

4.7 DeleteByRangeApplicationService:按范围删除的两种模式

DeleteByRangeApplicationService是顶层文档点名的服务之一:"share range-based delete planning, persistence, undo/redo, and progress streaming for delete-by-range handlers"(共享基于范围的删除规划、持久化、撤销/重做与进度流)。它支持直接模式(direct)流式模式(stream)

  • 直接模式delete()(对应 DeleteByRangeApplicationService.ts):prepareDeletePlan(按 range 类型解析目标记录、合并视图的 filter/sort/group、替换current user标签、构建删除快照)→ 准备并 guard 插件 → 单事务deleteManyInSingleTransactionfinalizeDeletePlan(含撤销/重做栈追加)。
  • 流式模式createStream():面向超大范围删除,返回AsyncIterable<DeleteByRangeStreamEvent>,事件类型为progress | done | errorDeleteByRangeStreamProgressEvent携带phase: 'preparing' | 'deleting'batchIndextotalCountdeletedCountbatchDeletedCount)。内部把删除计划切成多个DeleteStreamChunkPlan(默认查询页大小常量DEFAULT_DELETE_QUERY_PAGE_SIZE = 500,流式事件缓冲上限MAX_DELETE_STREAM_BUFFERED_EVENTS = 64),逐 chunk 执行并把进度推入AsyncIterableQueue,供 HTTP 层以 SSE/流式响应回传进度。

该服务的所有步骤都被runInSpan包裹并打上teable.DeleteByRangeApplicationService.*teable.delete_modedirect/stream)、teable.range_typecolumns/rows/cells)等 span 属性,体现了 Teable 在编排层内置的可观测性标准。

4.8 其他值得关注的服务

顶层文档还提到两个服务,这里一并说明:

  • TableUpdateFlow 之外的 TableQueryService:提供跨 CommandHandler/QueryHandler 复用的通用查表操作(getByIdgetByIdInBaseexists),DeleteByRangeApplicationService 的prepareDeletePlan第一步就是tableQueryService.getById(context, command.tableId)
  • TableDeletionSideEffectService:删除表之前,向其他表显式派发OnTeableTableDeleted反应(reaction),包括 link-to-text 转换与依赖元数据清理(见 services/ARCHITECTURE.md)。

此外services/目录还包含FieldUpdateSideEffectServiceFieldCrossTableUpdateSideEffectServiceLinkFieldUpdateSideEffectServiceTableCreationServiceSchemaOperationRunnerServiceDuplicateRecordsApplicationServiceRecordBatchCreationServiceRecordBulkUpdateServiceRecordReorderServiceUndoRedoStackServiceTableSchemaOperationLifecycleServiceTableSchemaOperationRepairHandlerTableUpdateTransactionScope等,共同构成完整的编排能力矩阵。每个服务都配有同名.spec.ts测试,例如 TableUpdateFlow.spec.ts、FieldCreationSideEffectService 相关测试 与 DeleteByRangeApplicationService 目录内对应测试,是阅读实现行为的最佳辅助材料。

五、数据流串联:一次"建字段"请求如何穿越 application 层

把上述服务串起来,可以还原一个典型场景——用户在视图中新建一个 link 字段,请求在 v2 Core 中的编排路径大致为:

  1. 命令处理器接收CreateFieldCommand,通过ForeignTableLoaderService.load预加载对端表(缺失引用立即报错);
  2. 调用FieldCreationSideEffectService.preview在内存中预览跨表副作用(供数据安全限制等检查);
  3. 通过FieldCreationSideEffectService.execute逐表执行TableUpdateFlow,以事务落库,产出聚合后的领域事件;
  4. 命令处理器按需发布事件;
  5. 事件总线把FieldCreatedFieldUpdated等事件分发给投影处理器(如FieldCreatedRealtimeProjection),投影从快照缓存取数、写入实时引擎,前端实时刷新。

整个过程体现了 ARCHITECTURE.md 的三层约定:规则在领域(visitor/spec),编排在应用服务(services/),派生在投影(projections/)

六、给开发者的扩展与维护建议

6.1 新增一个应用服务时的自查清单

对照 ARCHITECTURE.md 与 services/ARCHITECTURE.md,新增服务时应确认:

  • 服务内没有领域规则:任何"该不该做、做成什么样"的判断都应委托给 domain 下的 visitor/spec,应用服务只负责"按什么顺序、在什么事务里、何时发布事件";
  • 不调用其他命令处理器:共享逻辑一律下沉为服务并在本层复用(对应 src/ARCHITECTURE.md 的分层规则);
  • 持久化后工作留给仓储:schema 刷新、回填重放等不应写在应用服务里;
  • 携带可观测性:参照@TraceSpan()runInSpan的习惯,为关键步骤打 span;
  • 配套.spec.ts:每个服务都有对应测试是本目录的既定惯例。

6.2 维护本架构文档的约定

本目录及所有子目录的ARCHITECTURE.md首行都有一个统一声明:"Declaration: If the folder I belong to changes, please update me, especially core domain concepts."——即目录结构或核心概念变化时,必须同步更新本文件,并在抽象概念处补充示例或示例文件路径。这也是整个 v2 core 仓库的文档纪律:架构注释与代码同源演进。

结语

Teable v2 Core 的 application 层用最朴素的方式回答了"编排逻辑放哪里"的问题:领域模型保持纯净,命令处理器保持轻量,所有跨聚合的协调、事务边界与事件发布统一收敛到 application/services 与 application/projections 中。无论是TableUpdateFlow对分库场景下 DDL 一致性的精细管理,还是DeleteByRangeApplicationService对超大规模删除的流式进度推进,亦或是RecordCreationService对插件、副作用、撤销/重做、事件发布的串联,都展示了一个生产级电子表格引擎在"编排层"应当具备的工程水准。以此为参照,你可以轻松定位任何写路径的编排入口,并遵循同一套约束继续扩展。

【免费下载链接】teable✨ AI Spreadsheet for Business项目地址: https://gitcode.com/GitHub_Trending/te/teable

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

子品牌被推荐了,能不能算作母品牌的AI推荐表现?

子品牌被推荐&#xff0c;可以说明品牌组合中有成员进入了相应候选&#xff0c;但不能自动认定母品牌本身也被推荐。两种结果都值得观察&#xff0c;却回答不同的问题&#xff1a;一个关注具体品牌的购买表现&#xff0c;另一个关注集团或母品牌名下业务的整体覆盖。先确定需要…

作者头像 李华
网站建设 2026/9/13 4:53:00

DataHub 本地跑通全流程:10 分钟从容器启动到看到血缘图

DataHub 本地跑通全流程&#xff1a;10 分钟从容器启动到看到血缘图 【免费下载链接】datahub The Context Platform for your Data and AI Stack 项目地址: https://gitcode.com/GitHub_Trending/da/datahub DataHub 本地部署其实没那么玄乎——装好 CLI、一条命令拉起…

作者头像 李华
网站建设 2026/9/13 4:52:52

RP2040 DMA内存传输原理与MicroPython实战指南

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

作者头像 李华
网站建设 2026/9/13 4:50:56

企业非法集资风险预测实战:特征工程与LightGBM调参全攻略

简介&#xff1a;一套围绕CCF「企业非法集资风险预测」赛题的完整算法源码与配套数据包&#xff0c;面向机器学习参赛者、金融风控学习者和相关毕设/项目开发人员&#xff0c;聚焦企业多维数据下的风险建模与预测。资源共27个文件&#xff0c;包含22个csv数据文件、2个Python脚…

作者头像 李华
网站建设 2026/9/13 4:47:57

gVisor GPU 实战:为 Llama-2-7B-Chat-HF 构建 TensorRT 引擎的完整流程

gVisor GPU 实战&#xff1a;为 Llama-2-7B-Chat-HF 构建 TensorRT 引擎的完整流程 【免费下载链接】gvisor Application Kernel for Containers 项目地址: https://gitcode.com/GitHub_Trending/gv/gvisor 本文基于 gVisor 仓库中 TensorRT 引擎构建指南 展开&#xff…

作者头像 李华