Docling 插件系统深度解析:基于 pluggy 扩展 OCR、布局与表格结构引擎

📅 发布时间:2026/9/5 18:59:59
Docling 插件系统深度解析:基于 pluggy 扩展 OCR、布局与表格结构引擎
Docling 插件系统深度解析基于 pluggy 扩展 OCR、布局与表格结构引擎【免费下载链接】doclingGet your documents ready for gen AI项目地址: https://gitcode.com/GitHub_Trending/do/doclingDocling 通过基于 pluggy 与 setuptools entrypoint 的插件机制允许第三方在不改动主包的前提下向转换管线注入新的 OCR 引擎、布局引擎与表格结构识别引擎。本文完整讲解插件的注册方式覆盖 pyproject.toml、poetry、setup.cfg、setup.py 四种打包配置、三类工厂factory约定的接口与继承要求、allow_external_plugins安全开关的源码实现以及doclingCLI 中--allow-external-plugins、--show-external-plugins等参数的用法带你掌握从打包发布到运行时选型的完整插件开发链路。插件加载机制pluggy setuptools entrypointDocling 的插件体系建立在一套两层机制之上插件发现层Docling 使用 pluggy 的PluginManager扫描已安装包在 setuptools 中声明的、组名为docling的 entrypoint每个 entrypoint 指向一个 Python 模块插件注册层每个被发现的模块内定义一个与工厂同名的可调用函数如ocr_engines()、layout_engines()、table_structure_engines()返回包含引擎类列表的字典由对应的BaseFactory子类完成登记。插件发现的核心实现位于 BaseFactory.load_from_pluginsdef load_from_plugins( self, plugin_name: Optional[str] None, allow_external_plugins: bool False ): plugin_name plugin_name or self.plugin_name plugin_manager PluginManager(plugin_name) plugin_manager.load_setuptools_entrypoints(plugin_name) for plugin_name, plugin_module in plugin_manager.list_name_plugin(): plugin_module_name str(plugin_module.__name__) if not allow_external_plugins and not plugin_module_name.startswith( docling. ): logger.warning( fThe plugin {plugin_name} will not be loaded because Docling is being executed with allow_external_pluginsfalse. ) continue attr getattr(plugin_module, self.plugin_attr_name, None) if callable(attr): config attr() self.process_plugin(config, plugin_name, plugin_module_name)从源码结构看加载流程可以归纳为四步PluginManager(docling)创建以docling为组名的插件管理器load_setuptools_entrypoints(docling)从已安装包的 entrypoint 元数据中加载插件模块逐一对每个(插件名, 模块)做外部插件过滤模块名不以docling.开头且未开启allow_external_plugins时直接跳过仅打印 warning这是第三方插件默认不可见的原因用getattr(plugin_module, self.plugin_attr_name)在模块上取与工厂匹配的函数OCR 工厂取ocr_engines布局工厂取layout_engines表格工厂取table_structure_engines若该属性可调用则执行它拿到配置字典交由process_plugin把列表中的每个类调用register登记。登记逻辑 BaseFactory.register 以cls.get_options_type()即引擎类声明的配置类为键存入_classes并记录FactoryMeta(kind, plugin_name, module)元信息若同一配置类已被注册则抛出ValueError外层process_plugin捕获后仅告警%r already registered因此插件名在生态内必须唯一、同一 kind 只允许存在一个引擎实现。工厂还通过 get_enum 用已注册的 kind 动态生成字符串枚举如OcrEnginecreate_instance则按type(options)查找引擎类并实例化——这就是选项类决定用哪个引擎的绑定方式。Docling 主包自带的默认插件集中定义在 docling/models/plugins/defaults.py是编写第三方插件时最好的参考起点def ocr_engines(): from docling.models.stages.ocr.auto_ocr_model import OcrAutoModel # ... Tesseract、EasyOCR、RapidOCR、Nemotron、KserveV2、macOS Vision 等 return { ocr_engines: [ OcrAutoModel, EasyOcrModel, # ... ] }声明插件entrypoint 的四种打包写法entrypoint 组名固定为docling值为你包内负责插件注册的模块dotted path。your_plugin_name是插件名必须在全 Docling 生态中唯一your_package.module指向定义注册函数的模块。不同打包系统的声明方式如下。pyproject.tomlPEP 621 / setuptools[project.entry-points.docling] your_plugin_name your_package.modulepoetry v1 的 pyproject.toml[tool.poetry.plugins.docling] your_plugin_name your_package.modulesetup.cfg[options.entry_points] docling your_plugin_name your_package.modulesetup.pyfrom setuptools import setup setup( # ..., entry_points { docling: [ your_plugin_name your_package.module ] } )无论使用哪种写法最终效果一致包安装后pkg_resources/importlib.metadata都能在docling组下找到your_plugin_name - your_package.module的映射供PluginManager.load_setuptools_entrypoints发现。插件工厂与接口约定Docling 当前提供三类可插拔工厂各自封装在 docling/models/factories/ 目录中均继承自 BaseFactory 并在构造时传入plugin_attr_name即插件模块中注册函数的名字OcrFactorysuper().__init__(ocr_engines)面向BaseOcrModelLayoutFactorysuper().__init__(layout_engines)面向BaseLayoutModelTableStructureFactorysuper().__init__(table_structure_engines)面向BaseTableStructureModel。工厂实例通过 docling/models/factories/init.py 中的get_ocr_factory()、get_layout_factory()、get_table_structure_factory()等函数创建并用lru_cache按allow_external_plugins取值缓存——这意味着同一进程内开关状态变化时需以不同参数调用才会触发重新加载。OCR 工厂OCR 工厂允许向 Docling 用户提供更多 OCR 引擎。插件模块your_package.module中的注册代码形如# Factory registration def ocr_engines(): return { ocr_engines: [ YourOcrModel, ] }其中YourOcrModel必须实现 BaseOcrModel抽象页面处理模型其__call__(conv_res, page_batch)接收转换结果与页面批次并返回处理后的页面提供从 OcrOptions 派生的选项类并通过类方法get_options_type()暴露该配置类型该协议定义在 BaseModelWithOptionsget_options_type()返回类型 以options关键字参数构造。OcrOptions携带kind字段如 tesseract、easyocr 等工厂即以kind生成引擎枚举成员用户在管线中通过选项类选择具体引擎。Layout 引擎工厂布局引擎工厂用于提供新的版面分析引擎# Factory registration def layout_engines(): return { layout_engines: [ YourLayoutModel, ] }YourLayoutModel必须实现 BaseLayoutModel并提供从 BaseLayoutOptions 派生的选项类。默认插件defaults.py 中layout_engines()注册了LayoutModel、LayoutObjectDetectionModel以及实验性的TableCropsLayoutModel。Table structure 引擎工厂表格结构工厂用于提供新的表格结构识别引擎# Factory registration def table_structure_engines(): return { table_structure_engines: [ YourTableStructureModel, ] }YourTableStructureModel必须实现 BaseTableStructureModel并提供从 BaseTableStructureOptions 派生的选项类。默认实现包括TableStructureModel、TableStructureModelV2与GraniteVisionTableStructureModel。此外从 defaults.py 的源码结构看插件注册函数并非只有文档所述三类——同一机制还驱动着picture_description()工厂PictureDescriptionFactory注册函数名为picture_description说明该插件框架是通用可扩展的新增一类引擎只需新增一个BaseFactory子类与对应的注册函数约定。启用第三方插件allow_external_plugins出于安全与可预测性考虑非docling包自身的插件默认不会加载见上文load_from_plugins中startswith(docling.)的过滤逻辑。第三方插件必须通过allow_external_plugins显式开启。该选项声明在 PdfPipelineOptions 中from docling.datamodel.base_models import InputFormat from docling.datamodel.pipeline_options import PdfPipelineOptions from docling.document_converter import DocumentConverter, PdfFormatOption pipeline_options PdfPipelineOptions() pipeline_options.allow_external_plugins True # -- enable external plugins pipeline_options.ocr_options YourOptions # -- your OCR options here pipeline_options.layout_options YourLayoutOptions # -- your layout options here pipeline_options.table_structure_options YourTableStructureOptions # -- your table structure options here doc_converter DocumentConverter( format_options{ InputFormat.PDF: PdfFormatOption( pipeline_optionspipeline_options ) } )使用要点allow_external_plugins True只是解除过滤开关具体选用哪个引擎仍由ocr_options/layout_options/table_structure_options传入的选项实例决定选项类的kind必须与插件注册时的配置类一致否则BaseFactory.create_instance会抛出RuntimeError并列出全部已知 class 供排查见 _err_msg_on_class_not_found三个选项位对应三个工厂可只启用其一例如仅替换 OCR 引擎而沿用默认布局与表格结构实现。使用doclingCLICLI 侧同样需要先开启外部插件才能选择新引擎相关参数定义在 docling/cli/main.pyallow_external_plugins、show_external_plugins两个选项# Show the external plugins docling --show-external-plugins # Run docling with a custom OCR engine docling --allow-external-plugins --ocr-engineNAME # Run docling with a custom layout engine docling --allow-external-plugins --layout-engineNAME # Run docling with a custom table structure engine docling --allow-external-plugins --table-structure-engineNAME其中--show-external-plugins的实现 show_external_plugins_callback 会分别以allow_external_pluginsTrue获取 OCR、布局、表格结构三个工厂并打印各自registered_kind即所有可见引擎的 kind 列表而--ocr-engine、--layout-engine、--table-structure-engine传入的NAME正是各工厂枚举成员名也就是选项类的kind。CLI 内部在默认路径下仍以allow_external_pluginsFalse构建工厂见 main.py仅在用户显式传参后才切换行为与 API 路径完全对称。小结与开发检查清单结合文档约定与 base_factory.py 的源码实现开发并验证一个 Docling 引擎插件可对照以下清单接口引擎类继承对应基类BaseOcrModel/BaseLayoutModel/BaseTableStructureModel选项类继承对应*Options并定义唯一kind注册模块内提供与工厂同名的注册函数返回{工厂键: [引擎类]}字典不要注册已被占用的kind会被静默跳过并告警;打包在 entrypoint 的docling组声明插件插件名保持生态内唯一验证docling --show-external-plugins确认 kind 出现在列表中再用--allow-external-plugins --engineNAME跑通转换参考实现以 docling/models/plugins/defaults.py 中 Tesseract、EasyOCR 等内置引擎的注册方式作为模板。需要说明的适用前提以上机制与参数均以当前仓库版本为准插件发现依赖包已通过 pip 等标准方式安装entrypoint 元数据可用外部插件加载始终需要用户显式授权allow_external_plugins/--allow-external-plugins未开启时任何第三方引擎都不会进入工厂注册表。【免费下载链接】doclingGet your documents ready for gen AI项目地址: https://gitcode.com/GitHub_Trending/do/docling创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考