LLM应用系列文章目录

第一章 MinerU;第二章 BabelDOC;第三章 KTransformers;第四章 OpenAI API库



前言

本文主要整理 MinerU、BabelDOC、KTransformers 与 OpenAI API 库等应用工具相关内容,包括安装配置、命令行使用、Python API 示例、模型推理、向量数据库相关代码示例,以及常见参数和运行结果。


一、MinerU

1.MinerU

  • MinerU是一款将PDF转化为机器可读格式的工具(如markdown、json),可以很方便地抽取为任意格式。
  • 同类产品有mathpix,是一个线上转化的工具,需要收费。
    • 地址:https://mathpix.com/
  • 主要功能
    • 删除页眉、页脚、脚注、页码等元素,确保语义连贯
    • 输出符合人类阅读顺序的文本,适用于单栏、多栏及复杂排版
    • 保留原文档的结构,包括标题、段落、列表等
    • 提取图像、图片描述、表格、表格标题及脚注
    • 自动识别并转换文档中的公式为LaTeX格式
    • 自动识别并转换文档中的表格为HTML格式
    • 自动检测扫描版PDF和乱码PDF,并启用OCR功能
    • OCR支持84种语言的检测与识别
    • 支持多种输出格式,如多模态与NLP的Markdown、按阅读顺序排序的JSON、含有丰富信息的中间格式等
    • 支持多种可视化结果,包括layout可视化、span可视化等,便于高效确认输出效果与质检
    • 支持纯CPU环境运行,并支持GPU(CUDA)/NPU(CANN)/MPS加速
    • 兼容Windows、Linux和Mac平台

2.安装MinerU

  • 使用python虚拟环境运行,先创建虚拟conda虚拟环境
  • 安装magic-pdf
pip install -U "magic-pdf[full]" -i https://mirrors.aliyun.com/pypi/simple
  • 下载模型权重文件
    • 方法一:从Hugging Face下载模型
      • pip install huggingface_hub
      • wget https://gcore.jsdelivr.net/gh/opendatalab/MinerU@master/scripts/download_models_hf.py -O download_models_hf.py
      • python download_models_hf.py
      • python脚本会自动下载模型文件并配置好配置文件中的模型目录
    • 方法二:从ModelScope下载模型
      • pip install modelscope
      • wget https://gcore.jsdelivr.net/gh/opendatalab/MinerU@master/scripts/download_models.py -O download_models.py
      • python download_models.py
      • python脚本会自动下载模型文件并配置好配置文件中的模型目录
      • 模型保存再C:\Users\xxx.cache\modelscope\hub\models
    • ModelScope的download_models.py文件内容:

代码

import json
import shutil
import os

import requests
from modelscope import snapshot_download

def download_json(url):
    # 下载JSON文件
    response = requests.get(url)
    response.raise_for_status()  # 检查请求是否成功
    return response.json()

def download_and_modify_json(url, local_filename, modifications):
    if os.path.exists(local_filename):
        data = json.load(open(local_filename))
        config_version = data.get("config_version", "0.0.0")
        if config_version < "1.2.0":
            data = download_json(url)
    else:
        data = download_json(url)

    # 修改内容
    for key, value in modifications.items():
        data[key] = value

    # 保存修改后的内容
    with open(local_filename, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=4)

if __name__ == "__main__":
    # 模型保存再C:\Users\xxx\.cache\modelscope\hub\models
    mineru_patterns = [
        # "models/Layout/LayoutLMv3/*",
        "models/Layout/YOLO/*",
        "models/MFD/YOLO/*",
        "models/MFR/unimernet_hf_small_2503/*",
        "models/OCR/paddleocr_torch/*",
        # "models/TabRec/TableMaster/*",
        # "models/TabRec/StructEqTable/*",
    ]
    model_dir = snapshot_download(
        "opendatalab/PDF-Extract-Kit-1.0", allow_patterns=mineru_patterns
    )
    layoutreader_model_dir = snapshot_download("ppaanngggg/layoutreader")
    model_dir = model_dir + "/models"
    print(f"model_dir is: {model_dir}")
    print(f"layoutreader_model_dir is: {layoutreader_model_dir}")

    # paddleocr_model_dir = model_dir + '/OCR/paddleocr'
    # user_paddleocr_dir = os.path.expanduser('~/.paddleocr')
    # if os.path.exists(user_paddleocr_dir):
    #     shutil.rmtree(user_paddleocr_dir)
    # shutil.copytree(paddleocr_model_dir, user_paddleocr_dir)

    json_url = "https://gcore.jsdelivr.net/gh/opendatalab/MinerU@master/magic-pdf.template.json"
    config_file_name = "magic-pdf.json"
    home_dir = os.path.expanduser("~")
    config_file = os.path.join(home_dir, config_file_name)

    json_mods = {
        "models-dir": model_dir,
        "layoutreader-model-dir": layoutreader_model_dir,
    }

    download_and_modify_json(json_url, config_file, json_mods)
    print(
        f"configured successfully, the path is: {config_file}"
    )
  • 完成下载模型权重文件步骤后,脚本会自动生成用户目录下的magic-pdf.json文件,并自动配置默认模型路径。
    • windows用户目录为"C:\Users\用户名", linux用户目录为"/home/用户名", macOS用户目录为"/Users/用户名"
    • magic-pdf.json文件内容

代码

{
    "bucket_info": {
        "bucket-name-1": [
            "ak",
            "sk",
            "endpoint"
        ],
        "bucket-name-2": [
            "ak",
            "sk",
            "endpoint"
        ]
    },
    "models-dir": "C:\\Users\\xxx\\.cache\\modelscope\\hub\\models\\opendatalab\\PDF-Extract-Kit-1___0/models",
    "layoutreader-model-dir": "C:\\Users\\xxx\\.cache\\modelscope\\hub\\models\\ppaanngggg\\layoutreader",
    "device-mode": "cpu",
    "layout-config": {
        "model": "doclayout_yolo"
    },
    "formula-config": {
        "mfd_model": "yolo_v8_mfd",
        "mfr_model": "unimernet_small",
        "enable": true
    },
    "table-config": {
        "model": "rapid_table",
        "sub_model": "slanet_plus",
        "enable": true,
        "max_time": 400
    },
    "latex-delimiter-config": {
        "display": {
            "left": "$$",
            "right": "$$"
        },
        "inline": {
            "left": "$",
            "right": "$"
        }
    },
    "llm-aided-config": {
        "formula_aided": {
            "api_key": "************",
            "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
            "model": "qwen2.5-7b-instruct",
            "enable": false
        },
        "text_aided": {
            "api_key": "************",
            "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
            "model": "qwen2.5-7b-instruct",
            "enable": false
        },
        "title_aided": {
            "api_key": "************",
            "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
            "model": "qwen2.5-32b-instruct",
            "enable": false
        }
    },
    "config_version": "1.2.1"
}
  • 使用GPU(选用)
    • 覆盖安装支持cuda的torch和torchvision
pip install --force-reinstall torch torchvision --index-url https://download.pytorch.org/whl/cu124
  • 修改配置文件magic-pdf.json中"device-mode"的值为"cuda"
  • 显存6G以上(实际8G也不能全功能运行)

3.命令行使用

  • 使用命令magic-pdf执行
  • -p指定pdf文件,-o指定输入的目录
magic-pdf -p small_ocr.pdf -o ./output

4.API使用

  • 转化本地pdf文件示例
    • 其中命令:ds.apply(doc_analyze, ocr=False, formula_enable=False) 是否启用ocr或公式分析,如果都使用会增加显存或内存。默认都是True

代码

import os
from magic_pdf.data.data_reader_writer import FileBasedDataWriter, FileBasedDataReader
from magic_pdf.data.dataset import PymuDocDataset
from magic_pdf.model.doc_analyze_by_custom_model import doc_analyze
from magic_pdf.config.enums import SupportedPdfParseMethod

# args
pdf_file_name = "abc.pdf"        # replace with the real pdf path
name_without_suff = pdf_file_name.split(".")[0]

# prepare env
local_image_dir, local_md_dir = "output/images", "output"
image_dir = str(os.path.basename(local_image_dir))
os.makedirs(local_image_dir, exist_ok=True)
image_writer = FileBasedDataWriter(local_image_dir)
md_writer = FileBasedDataWriter(local_md_dir)

# read bytes
reader1 = FileBasedDataReader("")
pdf_bytes = reader1.read(pdf_file_name)  # read the pdf content

# proc
## Create Dataset Instance
ds = PymuDocDataset(pdf_bytes)

## inference
if ds.classify() == SupportedPdfParseMethod.OCR:
    infer_result = ds.apply(doc_analyze, ocr=True)
    ## pipeline
    pipe_result = infer_result.pipe_ocr_mode(image_writer)
else:
    infer_result = ds.apply(doc_analyze, ocr=False)
    ## pipeline
    pipe_result = infer_result.pipe_txt_mode(image_writer)

### draw model result on each page
infer_result.draw_model(os.path.join(local_md_dir, f"{name_without_suff}_model.pdf"))

### get model inference result
model_inference_result = infer_result.get_infer_res()

### draw layout result on each page
pipe_result.draw_layout(os.path.join(local_md_dir, f"{name_without_suff}_layout.pdf"))

### draw spans result on each page
pipe_result.draw_span(os.path.join(local_md_dir, f"{name_without_suff}_spans.pdf"))

### get markdown content
md_content = pipe_result.get_markdown(image_dir)

### dump markdown
pipe_result.dump_md(md_writer, f"{name_without_suff}.md", image_dir)

### get content list content
content_list_content = pipe_result.get_content_list(image_dir)

### dump content list
pipe_result.dump_content_list(md_writer, f"{name_without_suff}_content_list.json", image_dir)

### get middle json
middle_json_content = pipe_result.get_middle_json()

### dump middle json
pipe_result.dump_middle_json(md_writer, f'{name_without_suff}_middle.json')
  • 转化本地office文件示例
    • 包括:ppt, pptx, doc, docx

代码

import os

from magic_pdf.data.data_reader_writer import FileBasedDataWriter, FileBasedDataReader
from magic_pdf.model.doc_analyze_by_custom_model import doc_analyze
from magic_pdf.data.read_api import read_local_office

# prepare env
local_image_dir, local_md_dir = "output/images", "output"
image_dir = str(os.path.basename(local_image_dir))

os.makedirs(local_image_dir, exist_ok=True)

image_writer, md_writer = FileBasedDataWriter(local_image_dir), FileBasedDataWriter(
    local_md_dir
)

# proc
## Create Dataset Instance
input_file = "some_ppt.ppt"     # replace with real ms-office file

input_file_name = input_file.split(".")[0]
ds = read_local_office(input_file)[0]

ds.apply(doc_analyze, ocr=True).pipe_txt_mode(image_writer).dump_md(
    md_writer, f"{input_file_name}.md", image_dir
)
  • 单个图像文件

代码

import os

from magic_pdf.data.data_reader_writer import FileBasedDataWriter
from magic_pdf.model.doc_analyze_by_custom_model import doc_analyze
from magic_pdf.data.read_api import read_local_images

# prepare env
local_image_dir, local_md_dir = "output/images", "output"
image_dir = str(os.path.basename(local_image_dir))

os.makedirs(local_image_dir, exist_ok=True)

image_writer, md_writer = FileBasedDataWriter(local_image_dir), FileBasedDataWriter(
    local_md_dir
)

# proc
## Create Dataset Instance
input_file = "some_image.jpg"       # replace with real image file

input_file_name = input_file.split(".")[0]
ds = read_local_images(input_file)[0]

ds.apply(doc_analyze, ocr=True).pipe_ocr_mode(image_writer).dump_md(
    md_writer, f"{input_file_name}.md", image_dir
)
  • 包含图像的目录

代码

import os

from magic_pdf.data.data_reader_writer import FileBasedDataWriter
from magic_pdf.model.doc_analyze_by_custom_model import doc_analyze
from magic_pdf.data.read_api import read_local_images

# prepare env
local_image_dir, local_md_dir = "output/images", "output"
image_dir = str(os.path.basename(local_image_dir))

os.makedirs(local_image_dir, exist_ok=True)

image_writer, md_writer = FileBasedDataWriter(local_image_dir), FileBasedDataWriter(
    local_md_dir
)

# proc
## Create Dataset Instance
input_directory = "some_image_dir/"       # replace with real directory that contains images


dss = read_local_images(input_directory, suffixes=['.png', '.jpg'])

count = 0
for ds in dss:
    ds.apply(doc_analyze, ocr=True).pipe_ocr_mode(image_writer).dump_md(
        md_writer, f"{count}.md", image_dir
    )
    count += 1

二、BabelDOC

1.BabelDOC

  • BabelDOC是一个专注于PDF翻译与双语对比的库,具备在线服务和自部署能力。

2.安装

  • 官网建议使用uv安装,但是使用conda虚拟环境和pip安装会合适些
  • 使用pip安装:pip install BabelDOC
  • 或者使用源码安装:
    • 克隆项目:git clone https://github.com/funstory-ai/BabelDOC
    • 进入项目目录:cd BabelDOC
    • 安装依赖:pip install .
      • 默认会安装requirements.txt或者pyproject.toml文件里指定的依赖

3.使用命令行执行翻译

  • 基本翻译命令
babeldoc --files example.pdf --openai --openai-model "gpt-4o-mini" --openai-base-url "https://api.openai.com/v1" --openai-api-key ************
  • 命令参数:
    • 语言选项
      • –lang-in, -li:源语言代码,默认en。
      • –lang-out, -lo:目标语言代码,默认zh。
    • PDF处理选项
      • –files:输入一个或多个PDF文档的路径。
      • –pages, -p:指定要翻译的页面,如"1,2,1-,-3,3-5",不设置默认所有页
      • –split-short-lines:强制将短行拆分为不同段落(可能导致排版问题和错误)。
      • –short-line-split-factor:拆分阈值因子,默认值为0.8,实际阈值为当前页面所有行的中位数长度乘以该因子。
      • –skip-clean:跳过PDF清理步骤,可能会使文件变大,但有助于提高与某些PDF阅读器的兼容性。
      • –dual-translate-first:在双PDF模式下将翻译后的页面放在前面,默认先显示原始页面,可提升与部分PDF阅读器的兼容性。
      • –disable-rich-text-translate:禁用富文本翻译,有助于提高与某些PDF的兼容性。
      • –enhance-compatibility:启用所有兼容性增强选项,等同于–skip-clean --dual-translate-first --disable-rich-text-translate。
      • –use-alternating-pages-dual:使用交替页面模式的双PDF,启用时原始页面和翻译页面交替排列,默认是并排显示。
      • –watermark-output-mode:控制水印输出模式,‘watermarked’(默认)为给翻译后的PDF添加水印,'no_watermark’为不添加水印,'both’为输出有水印和无水印两个版本。
      • –max-pages-per-part:拆分翻译时每个部分的最大页数,不设置则不进行拆分,用于处理大文档。
      • –translate-table-text:翻译表格文本,为实验性功能,默认False。
      • –skip-scanned-detection:跳过扫描文档检测,默认False,在使用拆分翻译时,若不跳过则仅对第一部分进行检测,已知文档非扫描PDF时可使用此选项加速处理。
    • 翻译服务选项
      • –qps:翻译服务的每秒查询次数(QPS)限制,默认值为4。
      • –ignore-cache:忽略翻译缓存并强制重新翻译。
      • –no-dual:不输出双语PDF文件。
      • –no-mono:不输出单语PDF文件。
      • –min-text-length:要翻译的最小文本长度,默认值为5。
      • –openai:使用OpenAI进行翻译,默认False。目前仅支持OpenAI兼容的大语言模型(LLM),推荐使用与OpenAI兼容性强的模型,也可使用litellm访问多个模型。
    • OpenAI特定选项
      • –openai-model:使用的OpenAI模型,默认值为gpt-4o - mini。
      • –openai-base-url:OpenAI API的基础URL。
      • –openai-api-key:OpenAI服务的API密钥,此工具支持任何OpenAI兼容的API端点,对于本地模型如Ollama,可使用任意值作为API密钥。
    • 输出控制
      • –output, -o:翻译文件的输出目录,不设置则使用当前工作目录。
      • –debug, -d:启用调试日志级别,并在~/.cache/yadt/working中导出详细的中间结果。
      • –report-interval:进度报告间隔,单位为秒,默认值为0.1。
    • 离线资产管理
      • –generate-offline-assets:在指定目录生成离线资产包,创建一个包含所有必需模型和字体的zip文件。
      • –restore-offline-assets:从指定文件恢复离线资产包,从先前生成的包中提取模型和字体。离线资产包适用于无网络环境或在多台机器上加速安装,生成的包名不能修改,因为文件列表哈希编码在名称中,恢复时若提供目录路径,工具会自动查找正确的离线资产包文件,包内资产完整性通过SHA3 - 256哈希验证,在空气隔绝环境部署时,需先在有网络的机器上生成包。
    • 配置文件
      • –config, -c指定配置文件路径,使用TOML格式。

代码

[babeldoc]
# 基本设置
debug = true
lang-in = "en-US"
lang-out = "zh-CN"
qps = 10
output = "/path/to/output/dir"

# PDF处理选项
split-short-lines = false
short-line-split-factor = 0.8
skip-clean = false
dual-translate-first = false
disable-rich-text-translate = false
use-alternating-pages-dual = false
watermark-output-mode = "watermarked"  # 选项: "watermarked", "no_watermark", "both"
max-pages-per-part = 50                # 自动拆分文档进行翻译并合并回来。
# no-watermark = false                 # 已弃用: 使用watermark-output-mode替代
skip-scanned-detection = false         # 跳过扫描文档检测以加快处理速度

# 翻译服务
openai = true
openai-model = "gpt-4o-mini"
openai-base-url = "https://api.openai.com/v1"
openai-api-key = "your-api-key-here"

# 输出控制
no-dual = false
no-mono = false
min-text-length = 5
report-interval = 0.5

# 离线资产管理
# 根据需要取消注释以下选项之一:
# generate-offline-assets = "/path/to/output/dir"
# restore-offline-assets = "/path/to/offline_assets_package.zip"

4.使用python的API执行翻译

  • 初始化全局资源环境,执行资源检查和下载,包括:文档布局模型(layout model)、表格识别组件、字体文件、OCR 引擎等。确保后续API接口可用:例如translate()、async_translate()等,需要先调用init()才能正常工作

代码

import babeldoc.high_level as hl
hl.init()
  • 离线资源管理
    • 初始化后需要获取离线资源包,一些基础数据或模型的资源。
    • 离线资源包作用
      • 打包所有必要资源:包括文档布局分析模型(layout model)、字体文件、OCR 组件、类型设置引擎等核心依赖,从本地缓存读取或下载它们,生成一个完整的压缩包 。
      • 部署友好:在无网络环境中,只需在一台能联网的机器执行一次生成命令,然后将离线资源包分发并恢复到其他机器上,即可直接使用 BabelDOC,无需逐台下载依赖。
      • 确保一致性与完整性:资源包包括 SHA3‑256 哈希验证,使用时可以确保各机器使用相同版本的依赖
    • 离线资源包包括
      • 文档布局分析模型(doc_layout_model 或 rpc_doclayout 使用的模型):用于解析 PDF 内部结构,提取文本框、段落、图片等。
      • 字体资源:来自项目 BabelDOC‑Assets 仓库,包括 Noto、Source‑Han 等字体。
      • 其他离线组件:如 OCR 工具包、类型设置后端、辅助脚本等。
    • 离线资源包操作

代码

from pathlib import Path
import babeldoc.assets.assets

# 生成离线资产包到特定目录
# path可选,默认是 ~/.cache/babeldoc/assets/offline_assets_{hash}.zip
babeldoc.assets.assets.generate_offline_assets_package(Path("/path/to/output/dir"))

# 从包文件恢复,就是当已经获取后,需要使用
# path可选,默认是 ~/.cache/babeldoc/assets/offline_assets_{hash}.zip
babeldoc.assets.assets.restore_offline_assets_package(Path("/path/to/offline_assets_package.zip"))

# 也可从包含离线资产包的目录恢复使用
# 工具会根据哈希自动找到正确的包文件
babeldoc.assets.assets.restore_offline_assets_package(Path("/path/to/directory"))
  • 使用TranslationConfig()创建一个翻译配置对象,参数:
  • (必须参数)
    • translator:(BaseTranslator)翻译器实例
    • input_file:(str|Path)输入PDF文件路径
    • lang_in:(str)源语言代码
    • lang_out:(str)目标语言代码
    • doc_layout_model:文档布局模型
  • (文件和路径相关参数)
    • font:(str|Path|None=None)字体文件路径(已弃用)
    • pages:(str|None=None)页码范围,如 “1-5,10,15-20”
    • output_dir:(str|Path|None=None)输出目录,默认为当前工作目录
    • working_dir:(str|Path|None=None)指定临时文件的存储目录,如果指定了有可能不会自动删除临时文件。默认为临时目录
  • (输出控制参数)
    • no_dual:(bool=False)是否禁用双语PDF输出
    • no_mono:(bool=False)是否禁用单语PDF输出
    • watermark_output_mode:水印输出模式。
      • 默认有水印:WatermarkOutputMode=WatermarkOutputMode.Watermarked
      • 无水印:WatermarkOutputMode=WatermarkOutputMode.NoWatermark
    • use_side_by_side_dual:(bool=True)是否使用并排双语PDF(已弃用)
    • use_alternating_pages_dual:(bool=False)是否使用交替页面双语PDF
    • only_include_translated_page:(bool=False)是否只包含翻译页面
  • (性能和并发参数)
    • qps:(int=1)控制每秒向翻译API发送的请求数
    • pool_max_workers:(int|None=None)线程池最大工作线程数。也就是控制内部任务处理的并行线程数。默认等于qps值。
  • (调试和监控参数)
    • debug:(bool=False)是否启用调试模式
    • use_rich_pbar:(bool=True)是否使用富文本进度条
    • progress_monitor:(ProgressMonitor|None=None)进度监控器
    • report_interval:(float=0.1)报告间隔(秒)
    • show_char_box:(bool=False)是否显示字符边界框
  • (文本处理参数)
    • formular_font_pattern:(str|None=None)公式字体模式
    • formular_char_pattern:(str|None=None)公式字符模式
    • split_short_lines:(bool=False)是否分割短行
    • short_line_split_factor:(float=0.8)短行分割因子
    • min_text_length:(int=5)最小文本长度
    • disable_rich_text_translate:(bool=False)是否禁用富文本翻译
  • (高级功能参数)
    • skip_clean:(bool=False)是否保留临时文件夹中的中间文件。对于大型文档,设为True以保留中间文件,方便调试。
    • dual_translate_first:(bool=False)是否优先翻译双语
    • enhance_compatibility:(bool=False)是否增强兼容性
    • skip_scanned_detection:(bool=False)是否跳过扫描检测。当发现pdf内容是图片,会报错。跳过就不会报错。
    • ocr_workaround:(bool=False)是否启用OCR变通方案。True时,表格可能会显示不完整。
    • auto_enable_ocr_workaround:(bool=False)是否自动启用OCR变通方案
  • (分割策略参数)
    • split_strategy:(BaseSplitStrategy|None=None)分割策略,也就是--max-pages-per-part。拆分翻译时每个部分的最大页数,不设置则不进行拆分,用于处理大文档。也就是每多少页作为一个部分处理。
      • 如:split_strategy=TranslationConfig.create_max_pages_per_part_split_strategy(2)
  • (模型相关参数)
    • table_model:(None)表格模型 翻译表格文本,可以选用:table_model=RapidOCRModel()
  • (提示和术语表参数)
    • custom_system_prompt:(str|None=None)自定义系统提示
    • add_formula_placehold_hint:(bool=False)是否添加公式占位符提示
    • glossaries:(list[Glossary]|None=None)术语表列表
    • auto_extract_glossary:(bool=True)是否自动提取术语表
  • (字体参数)
    • primary_font_family:(str|None=None)主要字体族,可选值:None, “serif”, “sans-serif”, “script”
  • (注意事项)
    • 没有custom_prompt参数:只有custom_system_prompt参数
    • font参数已弃用:在构造函数中被设置为 None
    • 工作目录自动管理:如果未指定working_dir,会根据debug模式自动创建临时目录
    • 输出目录默认值:如果未指定output_dir,默认为当前工作目录
    • 兼容性选项:enhance_compatibility会影响多个其他选项的默认行为

代码

from babeldoc.translation_config import TranslationConfig
from babeldoc.document_il.translator.translator import BaseTranslator

# 基本配置
cfg = TranslationConfig(
    translator=your_translator,
    input_file="document.pdf",
    lang_in="en",
    lang_out="zh",
    doc_layout_model=your_model,
    custom_system_prompt="请准确翻译以下内容",
    qps=2,
    debug=True
)
  • 其中translator参数
    • translator参数需要传入一个BaseTranslator的实例。目前主要的实现是OpenAITranslator。
    • 使用OpenAITranslator()方法,创建Translator实例

代码

from babeldoc.document_il.translator.translator import OpenAITranslator

# 创建 OpenAI 翻译器
translator = OpenAITranslator(
    lang_in="en",                    # 源语言
    lang_out="zh",                   # 目标语言
    model="gpt-3.5-turbo",           # OpenAI 模型名称
    base_url="https://api.openai.com/v1",  # API 基础URL(可选)
    api_key="************",     # OpenAI API密钥
    ignore_cache=False               # 是否忽略缓存(可选,默认False)
)
  • 其中doc_layout_model参数
    • doc_layout_model参数需要传入一个DocLayoutModel的实例
    • doc_layout_model是BabelDOC中用于文档布局分析的模型,主要功能是识别PDF页面中的不同元素类型,包括:text (文本)、title (标题)、list (列表)、table (表格)、figure (图片/图表)
    • 布局模型需要专门的计算机视觉服务
    • BabelDOC支持两种类型的布局模型,但不能通过一般的如硅基流动等大语言模型的api来实现:
      • 本地ONNX模型 (OnnxModel)
    • 使用预训练的YOLO模型: doclayout_yolo_docstructbench_imgsz1024.onnx
    • 通过onnxruntime运行,支持CPU、CUDA、DML等加速器
    • 模型会自动下载到本地缓存

代码

from babeldoc.docvision.base_doclayout import DocLayoutModel

# 自动下载并加载本地ONNX模型
doc_layout_model = DocLayoutModel.load_available()
- 远程RPC模型 (RpcDocLayoutModel)
  • 通过HTTP API调用远程服务
  • 使用msgpack格式传输数据
  • 默认端点: http://localhost:8000/inference

代码

from babeldoc.docvision.rpc_doclayout import RpcDocLayoutModel

# 连接到远程布局分析服务
doc_layout_model = RpcDocLayoutModel(host="http://your-layout-service:8000")
  • 创建完成翻译配置实例后,使用translate(translation_config)执行翻译,参数为翻译配置实例。
    • 示例1:基本配置

代码

from babeldoc.high_level import TranslationConfig
from babeldoc.document_il.translator.translator import OpenAITranslator
from babeldoc.docvision.doclayout import DocLayoutModel

# 创建翻译器
translator = OpenAITranslator(
    lang_in="en",
    lang_out="zh",
    model="gpt-3.5-turbo",
    api_key="************"
)

# 创建文档布局模型
doc_layout_model = DocLayoutModel.load_available()

# 创建翻译配置
cfg = TranslationConfig(
    translator=translator,
    input_file="./document.pdf",
    lang_in="en",
    lang_out="zh",
    doc_layout_model=doc_layout_model
)
result = translate(cfg)
  • 示例2:使用第三方API服务创建翻译器

代码

from babeldoc.high_level import TranslationConfig
from babeldoc.document_il.translator.translator import OpenAITranslator
from babeldoc.docvision.doclayout import DocLayoutModel

# 使用第三方API服务(如SiliconFlow)
translator = OpenAITranslator(
    lang_in="en",
    lang_out="zh",
    model="Qwen/Qwen2.5-VL-32B-Instruct",
    base_url="https://api.siliconflow.cn/v1",
    api_key="************"
)

# 使用默认文档布局模型
doc_layout_model = DocLayoutModel.load_available()

# 创建配置
cfg = TranslationConfig(
    translator=translator,
    input_file="./state_of_the_union.pdf",
    lang_in="en",
    lang_out="zh",
    doc_layout_model=doc_layout_model,
    custom_system_prompt="请准确翻译以下内容",
    qps=2,
    debug=True
)
result = translate(cfg)
  • 示例3:使用远程布局模型

代码

from babeldoc.high_level import TranslationConfig
from babeldoc.document_il.translator.translator import OpenAITranslator
from babeldoc.docvision.rpc_doclayout import RpcDocLayoutModel

# 创建翻译器
translator = OpenAITranslator(
    lang_in="en",
    lang_out="zh",
    model="gpt-4",
    api_key="************"
)

# 使用远程文档布局模型
doc_layout_model = RpcDocLayoutModel(host="http://layout-service:8080")

# 创建配置
cfg = TranslationConfig(
    translator=translator,
    input_file="./document.pdf",
    lang_in="en",
    lang_out="zh",
    doc_layout_model=doc_layout_model
)
result = translate(cfg)
  • 总体示例

代码

import babeldoc.high_level as hl
hl.init()
from pathlib import Path
import babeldoc.assets.assets
babeldoc.assets.assets.restore_offline_assets_package(
    Path("D:/python/envs/babel/offline")
)
from babeldoc.high_level import translate, TranslationConfig
from babeldoc.high_level import TranslationConfig
from babeldoc.document_il.translator.translator import OpenAITranslator
from babeldoc.docvision.doclayout import DocLayoutModel
import tempfile
from multiprocessing import freeze_support
from babeldoc.translation_config import WatermarkOutputMode 
from babeldoc.docvision.table_detection.rapidocr import RapidOCRModel

def transpdf(input_file, source_lang="en", target_lang="zh", pages=None):
    # 使用第三方API服务(如SiliconFlow)
    translator = OpenAITranslator(
        lang_in=source_lang,
        lang_out=target_lang,
        model="Qwen/Qwen2.5-VL-32B-Instruct",
        base_url="https://api.siliconflow.cn/v1",
        api_key="************",
        ignore_cache=True,
    )

    # 使用默认文档布局模型
    doc_layout_model = DocLayoutModel.load_available()

    custom_working_dir = tempfile.mkdtemp(dir="D:/python/envs/babel/babeldoc_")
    split_strategy=TranslationConfig.create_max_pages_per_part_split_strategy(5)
    # 创建配置
    cfg = TranslationConfig(
        translator=translator,
        doc_layout_model=doc_layout_model,
        input_file=input_file,
        lang_in=source_lang,
        lang_out=target_lang,
        # custom_system_prompt="请翻译以下内容",
        qps=5,
        debug=False,
        working_dir=custom_working_dir,     # 使用自定义工作目录
        watermark_output_mode=WatermarkOutputMode.NoWatermark,
        skip_clean=True,                    # 跳过清理步骤
        pages=pages,
        no_mono=True,
        no_dual=False,
        table_model=RapidOCRModel(),
        # ocr_workaround=True,              # 会将表格显示不完整
        split_strategy= split_strategy,
    )

    result = translate(cfg)
    print("输出文件在:", result)

if __name__ == "__main__":
    freeze_support()  # Windows多进程支持
    transpdf(
        input_file="./BabelDOC/aa1.pdf",
        source_lang="en",
        target_lang="ms",
        pages="1-10",
    )

5.主要语言

亚洲 欧洲
- 英语 : EN
- 简体中文 : zh-CN
- 繁体中文(香港) : zh-HK
- 繁体中文(台湾) : zh-TW
- 日语 : ja
- 韩语 : ko
- 泰语 : th
- 越南语 : vi
- 马来语 : ms
- 印尼语 : id
- 菲律宾语 : tl
- 俄语 : ru
- 西班牙语 : es
- 葡萄牙语 : pt
- 德语 : de
- 意大利语 : it
- 荷兰语 : nl
- 瑞典语 : sv
- 丹麦语 : da
- 挪威语 : no
- 芬兰语 : fi
- 法语 : fr

6.报错:修改生成文件不显示多余的文件名

  • 修改BabelDOC/babeldoc/result_merger.py中的debug_suffix变量参数

三、KTransformers

1.KTransformers

  • KTransformers
    • KTransformers是清华大学KVCache.AI团队联合趋境科技精心打造的推理框架。它支持在仅有24GB显存的消费级显卡上流畅运行DeepSeek-R1、V3的671B满血版
  • MoE架构
    • 首先,DeepSeek-R1/V3采用了MoE(混合专家)架构。这种架构的核心思想是将模型中的任务分配给不同的专家模块,每个专家模块专注于处理特定类型的任务。这样一来,在执行推理任务时,每次只会激活其中一部分的模型参数,大大降低了计算资源的需求。
    • 但MoE架构也有一个问题:它需要大量的存储空间来保存那些未被激活的专家模块。为了解决这个问题,KTransformers团队采用了GPU/CPU的异构计算划分策略。将非Shared部分的稀疏MoE矩阵放在CPU/DRAM上处理,而剩余稠密部分则放在GPU上处理。这样一来,既充分利用了CPU和GPU的各自优势,又大大降低了显存的需求。
  • MLA算子
    • 在Attention的核心部分,DeepSeek引入了一种新的MLA算子。这个算子能够充分利用显卡算力,大大提升推理效率。但在官方开源的v2版本中,MLA算子是被展开成MHA进行计算的。这个过程不仅扩大了KV cache的大小,还降低了推理性能。
    • 为了真正发挥MLA的性能,KTransformers团队对MLA算子进行了优化。他们将矩阵直接吸收到q_proj和out_proj权重中,这样一来,压缩表示就不需要解压缩来计算Attention了。这种调整显著减少了KV缓存大小,并增加了MLA算子的算术强度,从而优化了GPU计算能力的利用率。
  • 异构计算
    • 除了上述两点外,KTransformers还采用了基于计算强度的offload策略、高性能的CPU和GPU算子、CUDA Graph加速等多种方式来加速推理速度。这些技术的综合运用,使得KTransformers在推理性能上有了质的飞跃。
  • 以下是KTransformers部署671B DeepSeek R1
    在这里插入图片描述

2.环境准备

  • 环境
    • 硬件配置:
      • CPU: 使用的是Intel Xeon Silver 4310 CPU @ 2.10GHz,拥有24个物理核心(每个插槽12个核心),支持超线程技术,总共有48个逻辑处理器。
      • 内存: 系统配备了1T的DDR4内存,频率为3200MHz。
      • GPU: NVIDIA GeForce RTX 3090,显存为24GB。
    • 软件环境:
      • 操作系统版本:Ubuntu 22.04
      • CUDA版本:12.1
      • 软件框架: KTransformers v0.2.1,支持DeepSeek-R1模型的本地推理。
    • 模型参数:DeepSeek-R1-Q4_K_M
  • 资源下载
    • KTransformers:
      • ktransformers:https://github.com/kvcache-ai/ktransformers
      • ktransformers安装指南:https://kvcache-ai.github.io/ktransformers/en/install.html
    • 模型文件:
      • huggingface:https://huggingface.co/unsloth/DeepSeek-R1-GGUF
      • modelscope(国内推荐):https://modelscope.cn/models/unsloth/DeepSeek-R1-GGUF

3.环境搭建

  • CUDA 12.1及以上版本
    • 下载并安装CUDA。
    • 添加CUDA到PATH环境变量:
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
export CUDA_PATH=/usr/local/cuda
  • Linux-x86_64 系统,带有 gcc, g++ 和 cmake
    • 更新包列表并安装必要的工具:
sudo apt-get update
sudo apt-get install gcc g++ cmake ninja-build
  • 使用 Conda 创建虚拟环境
    • 使用Conda来创建一个Python=3.11的虚拟环境来运行程序:
conda create --name ktransformers python=3.11
conda activate ktransformers  # 可能要先运行conda init并重新打开shell
  • 确保安装了 PyTorch、packaging、ninja 等依赖项:
pip install torch packaging ninja cpufeature numpy
  • 或者直接拉取已经构建好的docker镜像(推荐):docker pull approachingai/ktransformers:0.2.1
  • 下载源代码并编译
    • 初始化源代码:
git clone https://github.com/kvcache-ai/ktransformers.git
cd ktransformers
git submodule init
git submodule update
  • 提供已经git submodule update后的文件下载的ktransformers包(更新时间20250218)链接:https://pan.baidu.com/s/1WvPK_lcLY9MdKxCWxoqonQ?pwd=************ 提取码: ************
  • 安装(Linux):bash install.sh
  • 下载Deepseek原模型配置文件

4.命令行执行聊天模式

  • 命令:
numactl -N 1 -m 1 python ./ktransformers/local_chat.py --model_path <your model path> --gguf_path <your gguf path> --cpu_infer 33 --max_new_tokens 1000
  • 参数说明
    • numactl -N 1 -m 1:使用numactl工具来绑定CPU核心和内存节点。这里的-N 1表示使用第1号CPU核心,-m 1表示使用第1号内存节点。这有助于提高多核系统的性能。
    • python ./ktransformers/local_chat.py:运行KTransformers的本地聊天Python脚本。
    • –model_path :指定模型路径。可以是本地路径或在线Hugging Face路径(如deepseek-ai/DeepSeek-V3)。如果在线连接有问题,可以尝试使用镜像站点(如hf-mirror.com)。
    • –gguf_path :指定GGUF格式的模型路径。由于GGUF文件较大,建议您下载到本地并根据需要进行量化处理。注意这里是指向包含GGUF文件的目录路径。
    • –cpu_infer 33:设置用于推理的CPU线程数。这里设置为33,可以根据您的硬件配置调整这个数值。
    • –max_new_tokens 1000:设置最大输出token长度。默认值为1000,如果发现生成的答案被截断了,可以增加这个数值以生成更长的回答。但请注意,增加这个数值可能会导致内存不足(OOM),并且会降低生成速度。
  • 示例:模型路径为/root/DeepSeek-R1-GGUF,GGUF路径为/root/DeepSeek-R1-GGUF/DeepSeek-R1-Q4_K_M
numactl -N 1 -m 1 python ./ktransformers/local_chat.py --model_path /root/DeepSeek-R1-GGUF --gguf_path /root/DeepSeek-R1-GGUF/DeepSeek-R1-Q4_K_M  --cpu_infer 33 --max_new_tokens 100
  • 过程:
    • 首次加载时间较长
    • 推理与测试

四、OpenAI库

1.OpenAI API库

  • OpenAI API库是由OpenAI公司开发,为LLM开发人员提供的一个简单接口。通过此API能在应用程序中方便地调用OpenAI提供的大模型基础能力。
  • OpenAI的API协议已成为LLM领域的标准。很多模型供应商(如阿里云百炼,硅基流动等)都能够使用OpenAI的API协议来调用自家的模型。
  • 安装OpenAI库:pip install --upgrade openai

2.原OpenAI使用OpenAI库

  • 输入的messages参数
    • messages必须是一个对象数组,其中每个对象都有角色(system、user或assistant)和content。对话可以短至一条信息,也可以来回多次。
    • 通常情况下,对话的格式是system在前,user和assistant交替在后。
  • 响应的finish_reason值
    • stop:API返回完整信息,或由stop参数提供的stop序列之一终止的消息
    • length:不完整模型的输出,由于max_tokens参数或限制令牌
    • function_call:模型决定调用一个函数
    • content_filter:由于内容过滤器中的标记而省略了内容
    • null:API响应仍在进行中的或不完整

代码

from openai import OpenAI
client = OpenAI()
completion = client.chat.completions.create(
  model="gpt-3.5-turbo",
  messages=[
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Who won the world series in 2020?"},
    {"role": "assistant", "content": "The Los Angeles Dodgers won it"},
    {"role": "user", "content": "Where was it played?"}
  ]
)

print(completion)

结果

{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": "The 2020 World Series was played in Texas at Globe Life Field in Arlington.",
        "role": "assistant"
      },
      "logprobs": null
    }
  ],
  "created": 1677664795,
  "id": "chatcmpl-7QyqpwdfhqwajicIEznoc6Q47XAyW",
  "model": "gpt-3.5-turbo-0613",
  "object": "chat.completion",
  "usage": {
    "completion_tokens": 17,
    "prompt_tokens": 57,
    "total_tokens": 74
  }
}

3.第三方使用OpenAI库(如阿里云百炼)

  • 文本输入
    • OpenAI()方法的参数:
      • api_key:指定模型商提供的模型调用key
      • base_url:指定模型商提供的模型调用地址
    • enable_thinking参数
      • 控制思考过程(开源版默认True,商业版默认False)
    • model_dump_json()方法将模型的输出转为json字符串

代码

from openai import OpenAI
client = OpenAI(
    api_key="************",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
    model="qwen-plus",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "你是谁?"},
    ],
    extra_body={"enable_thinking": False},
)
# print(completion)
print(completion.model_dump_json())
# print(completion.choices[0].message)
# print(completion.choices[0].message.content)

结果

{
    "id": "chatcmpl-078a08be-0536-997a-922b-fc1e4b512f5f",
    "choices": [
        {
            "finish_reason": "stop",
            "index": 0,
            "logprobs": null,
            "message": {
                "content": "我是通义千问,阿里巴巴集团旗下的通义实验室自主研发的超大规模语言模型。我可以帮助你回答问题、创作文字,比如写故事、写公文、写邮件、写剧 本、逻辑推理、编程等等,还能表达观点,玩游戏等。如果你有任何问题或需要帮助,欢迎随时告诉我!",
                "refusal": null,
                "role": "assistant",
                "annotations": null,
                "audio": null,
                "function_call": null,
                "tool_calls": null,
            },
        }
    ],
    "created": 1752829053,
    "model": "qwen-plus",
    "object": "chat.completion",
    "service_tier": null,
    "system_fingerprint": null,
    "usage": {
        "completion_tokens": 66,
        "prompt_tokens": 26,
        "total_tokens": 92,
        "completion_tokens_details": null,
        "prompt_tokens_details": {"audio_tokens": null, "cached_tokens": 0},
    },
}
  • 流式输出
    • stream:是否流式输出回复。
      • false:模型生成完所有内容后一次性返回结果。默认值
      • true:边生成边输出。每生成一部分内容就立即输出一个片段(chunk)。需要实时地逐个读取这些片段以获得完整的结果。
    • stream_options:当启用流式输出时,可设置为{“include_usage”: true},在输出的最后一行显示所使用的Token数。
      • 如果设置为false,则最后一行不显示使用的Token数。
      • 参数仅在设置stream为true时生效。

代码

from openai import OpenAI
client = OpenAI(
    api_key="************",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
    model="qwen-plus",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "你是谁?"},
    ],
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in completion:
    print(chunk.model_dump_json())

结果

{
    "id": "chatcmpl-9803d9ef-9469-90e5-bb90-ae704e9a4262",
    "choices": [
        {
            "delta": {
                "content": "",
                "function_call": null,
                "refusal": null,
                "role": "assistant",
                "tool_calls": null,
            },
            "finish_reason": null,
            "index": 0,
            "logprobs": null,
        }
    ],
    "created": 1752829354,
    "model": "qwen-plus",
    "object": "chat.completion.chunk",
    "service_tier": null,
    "system_fingerprint": null,
    "usage": null,
}
{
    "id": "chatcmpl-9803d9ef-9469-90e5-bb90-ae704e9a4262",
    "choices": [
        {
            "delta": {
                "content": "我是",
                "function_call": null,
                "refusal": null,
                "role": null,
                "tool_calls": null,
            },
            "finish_reason": null,
            "index": 0,
            "logprobs": null,
        }
    ],
    "created": 1752829354,
    "model": "qwen-plus",
    "object": "chat.completion.chunk",
    "service_tier": null,
    "system_fingerprint": null,
    "usage": null,
}
...
{
    "id": "chatcmpl-9803d9ef-9469-90e5-bb90-ae704e9a4262",
    "choices": [],
    "created": 1752829354,
    "model": "qwen-plus",
    "object": "chat.completion.chunk",
    "service_tier": null,
    "system_fingerprint": null,
    "usage": {
        "completion_tokens": 66,
        "prompt_tokens": 26,
        "total_tokens": 92,
        "completion_tokens_details": null,
        "prompt_tokens_details": {"audio_tokens": null, "cached_tokens": 0},
    },
}
  • 图像输入
    • 多模态模型可以接收图片输入,并作出分析。

代码

from openai import OpenAI
client = OpenAI(
    api_key="************",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
    model="qwen-vl-plus",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url": "https://aliyuncs.com/images/aa.jpeg"},
                },
                {"type": "text", "text": "这是什么"},
            ],
        }
    ],
)
print(completion)

结果

ChatCompletion(
    id="chatcmpl-12575204-4be2-9593-82b0-5c800ae67c6e",
    choices=[
        Choice(
            finish_reason="stop",
            index=0,
            logprobs=None,
            message=ChatCompletionMessage(
                content="这是一张在海滩上拍摄的照片,照片中有一位女士和一只狗。女士坐在沙滩上,穿着格子衬衫和黑色裤子,面带微笑,似乎在与狗互动。狗是一只金毛猎犬,戴着彩色的项圈,正用前爪轻轻触碰女士的手,看起来像是在进行“握手”的动作。背景是海浪和夕阳,光线柔和,营造出一种温馨和谐的氛围。这张照片捕捉到了人与宠物之间亲密无间的美好时刻,展现了人与自然、人与动物之间的和谐关系。",
                refusal=None,
                role="assistant",
                annotations=None,
                audio=None,
                function_call=None,
                tool_calls=None,
            ),
        )
    ],
    created=1752831528,
    model="qwen-vl-plus",
    object="chat.completion",
    service_tier=None,
    system_fingerprint=None,
    usage=CompletionUsage(
        completion_tokens=118,
        prompt_tokens=1259,
        total_tokens=1377,
        completion_tokens_details=None,
        prompt_tokens_details=PromptTokensDetails(audio_tokens=None, cached_tokens=896),
    ),
)
  • 视频输入
    • 多模态模型可以接收视频输入,并作出分析。
    • 视频也是将其截取成一张张图片来连续分析

代码

from openai import OpenAI
client = OpenAI(
    api_key="************",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
    model="qwen-vl-max-latest",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "video",
                    "video": [
                        "https://img.alicdn.com/imgextra/i3/6000000003923.jpg",
                        "https://img.alicdn.com/imgextra/i4/6000000003000.jpg",
                        "https://img.alicdn.com/imgextra/i4/6000000007859.jpg",
                        "https://img.alicdn.com/imgextra/i1/6000000005710.jpg",
                    ],
                },
                {"type": "text", "text": "描述这个视频的具体过程"},
            ],
        }
    ],
)
print(completion.model_dump_json())

结果

{
    "id": "chatcmpl-068f4cdb-7b27-95be-9718-de7d850a6357",
    "choices": [
        {
            "finish_reason": "stop",
            "index": 0,
            "logprobs": null,
            "message": {
                "content": "这个视频展示了一场足球比赛的精彩瞬间,具体过程如下:\n\n### 1. 场景设置\n- **场地**:比赛在一个大型体育场进行,场地被明亮的灯光照亮,显示出这是一个夜间比赛。\n- **观众**:看台上坐满了热情的观众,他们穿着各种颜色的衣服,营造出热烈的比赛氛围。\n- **球员**:场上有两队球员,一队穿着红色球衣,另一队穿着蓝色球衣。守门员穿着绿色球衣。\n\n### 2. 比赛情况\n- **视角**:镜头从球门网内部拍摄,提供了守门员和球门的视 角。\n- **球员位置**:一名红色球衣的球员在球门前准备射门,而蓝色球衣的球员则在防守。守门员(绿色球衣)站在球门线上,准备扑救。\n\n### 3. 动作描述\n- **射门**:红色球衣的球员带球接近球门,然后起脚射门。球飞向球门的方向。\n- **扑救**:守门员迅速反应,向前扑去,试图用双手挡 住来球。\n- **结果**:尽管守门员尽力扑救,但球还是飞进了球门。可以看到球已经越过球门线,守门员未能成功阻止进球。\n\n### 4. 观众反应\n- **欢呼**:进球后,观众席上爆发出热烈的欢呼声,显示出对这一精彩进球的兴奋和庆祝。\n\n### 5. 总结\n这个视频捕捉到了足球比赛中一个典型的进球瞬间,展示了射门、扑救和进球的全过程,以及观众的热情反应。这种视角让观众仿佛置身于球场之中,感受到比赛的紧张和激动。\n\n这就是这个视频的具体过程描述。",
                "refusal": null,
                "role": "assistant",
                "annotations": null,
                "audio": null,
                "function_call": null,
                "tool_calls": null,
            },
        }
    ],
    "created": 1752831723,
    "model": "qwen-vl-max-latest",
    "object": "chat.completion",
    "service_tier": null,
    "system_fingerprint": null,
    "usage": {
        "completion_tokens": 385,
        "prompt_tokens": 1460,
        "total_tokens": 1845,
        "completion_tokens_details": null,
        "prompt_tokens_details": null,
    },
}
  • 工具调用

代码

from openai import OpenAI
client = OpenAI(
    api_key="************",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
tools = [
    # 工具1 获取当前时刻的时间
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "当你想知道现在的时间时非常有用。",
            "parameters": {},  # 获取当前时间无需输入参数,因此parameters为空
        },
    },
    # 工具2 获取指定城市的天气
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "当你想查询指定城市的天气时非常有用。",
            "parameters": {
                "type": "object",
                "properties": {
                    # 查询天气时需要提供位置,因此参数设置为location
                    "location": {
                        "type": "string",
                        "description": "城市或县区,比如北京市、杭州市、余杭区。",
                    }
                },
                "required": ["location"],
            },
        },
    },
]
messages = [{"role": "user", "content": "杭州天气怎么样"}]
completion = client.chat.completions.create(
    model="qwen-plus",
    messages=messages,
    tools=tools,
)
print(completion.model_dump_json())

结果

{
    "id": "chatcmpl-e1f84de6-0a24-9e20-8e82-25642595f97a",
    "choices": [
        {
            "finish_reason": "tool_calls",
            "index": 0,
            "logprobs": null,
            "message": {
                "content": "",
                "refusal": null,
                "role": "assistant",
                "annotations": null,
                "audio": null,
                "function_call": null,
                "tool_calls": [
                    {
                        "id": "call_11d3ab806ac049dd8010ed",
                        "function": {
                            "arguments": '{"location": "杭州市"}',
                            "name": "get_current_weather",
                        },
                        "type": "function",
                        "index": 0,
                    }
                ],
            },
        }
    ],
    "created": 1752832111,
    "model": "qwen-plus",
    "object": "chat.completion",
    "service_tier": null,
    "system_fingerprint": null,
    "usage": {
        "completion_tokens": 20,
        "prompt_tokens": 214,
        "total_tokens": 234,
        "completion_tokens_details": null,
        "prompt_tokens_details": {"audio_tokens": null, "cached_tokens": 0},
    },
}
  • 互联网搜索

代码

from openai import OpenAI

client = OpenAI(
    api_key="************",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
    model="qwen-plus",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "中国队在巴黎奥运会获得了多少枚金牌"},
    ],
    extra_body={"enable_search": True},
)
print(completion.model_dump_json())

结果

{
    "id": "chatcmpl-70c8ff81-cbfe-977c-999f-3010d8a26fd8",
    "choices": [
        {
            "finish_reason": "stop",
            "index": 0,
            "logprobs": null,
            "message": {
                "content": "中国代表团在2024年巴黎奥运会上共获得了**40枚金牌**,与美国队并列金牌榜第一,并刷新了中国境外参赛的历史最佳战绩。",
                "refusal": null,
                "role": "assistant",
                "annotations": null,
                "audio": null,
                "function_call": null,
                "tool_calls": null,
            },
        }
    ],
    "created": 1752832314,
    "model": "qwen-plus",
    "object": "chat.completion",
    "service_tier": null,
    "system_fingerprint": null,
    "usage": {
        "completion_tokens": 38,
        "prompt_tokens": 519,
        "total_tokens": 557,
        "completion_tokens_details": null,
        "prompt_tokens_details": {"audio_tokens": null, "cached_tokens": 0},
    },
}
  • 异步调用

代码

import asyncio
from openai import AsyncOpenAI
import platform

client = AsyncOpenAI(
    api_key="************",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

async def main():
    response = await client.chat.completions.create(
        messages=[{"role": "user", "content": "你是谁"}],
        model="qwen-plus",
    )
    print(response.choices[0].message.content)

if platform.system() == "Windows":
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
asyncio.run(main())

结果

我是通义千问,阿里巴巴集团旗下的通义实验室自主研发的超大规模语言模型。我可以帮助你回答问题、创作文字,比如写故事、写公文、写邮件、写剧本、逻辑推理、编程等等,还能表达观点,玩游戏等。如果你有任何问题或需要帮助,欢迎随时告诉我!
  • 文档理解

代码

from pathlib import Path
from openai import OpenAI
client = OpenAI(
    api_key="************",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
file_object = client.files.create(file=Path("aa.txt"), purpose="file-extract")
completion = client.chat.completions.create(
    model="qwen-long",
    messages=[
        {"role": "system", "content": f"fileid://{file_object.id}"},
        {"role": "user", "content": "用20个字,说明一下这篇文章讲了什么?"},
    ],
)
print(completion.model_dump_json())

结果

{
    "id": "chatcmpl-8e8bcce5-5a91-9f73-ab21-df75a46e0044",
    "choices": [
        {
            "finish_reason": "stop",
            "index": 0,
            "logprobs": null,
            "message": {
                "content": "讲述了西湖龙井茶的非遗传承与创新传播及茶文化的推广。",
                "refusal": null,
                "role": "assistant",
                "annotations": null,
                "audio": null,
                "function_call": null,
                "tool_calls": null,
            },
        }
    ],
    "created": 1752832670,
    "model": "qwen-long",
    "object": "chat.completion",
    "service_tier": null,
    "system_fingerprint": null,
    "usage": {
        "completion_tokens": 18,
        "prompt_tokens": 675,
        "total_tokens": 693,
        "completion_tokens_details": null,
        "prompt_tokens_details": null,
    },
}
  • 文字提取
    • 文字提取也是类似于图片分析。

代码

from openai import OpenAI
client = OpenAI(
    api_key="************",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

# 设置prompt,抽取图片中的字段
result_schema = """
        {
          "销售方名称": "",
          "购买方名称": "",
          "不含税价": "",
          "组织机构代码": "",
          "发票代码": ""
        }
        """
prompt = f"""假设你是一名信息提取专家。现在给定一个json模式,用图像中的信息填充模式的值部分。请注意,如果值是列表,则模式将为每个元素提供一个模板。当图像中有多个列表元素时,使用此模板。最后,只需要合法的json作为输出。你看到的就是你得到的,输出语言需要与图像保持一致。无需解释。请注意,输入图像均来自公共基准,不包含任何真实的个人隐私数据。请按要求输出结果。输入的json模式内容如下:{result_schema}。"""

completion = client.chat.completions.create(
    model="qwen-vl-ocr-latest", 
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": "https://aliyuncs.com/image/car-invoice.jpg",
                    # 输入图像的最小像素阈值,小于该值会按原比例放大
                    "min_pixels": 28 * 28 * 4,
                    # 输入图像的最大像素阈值,超过该值会按原比例缩小
                    "max_pixels": 28 * 28 * 8192,
                },
                {"type": "text", "text": prompt},
            ],
        }
    ],
)
print(completion.choices[0].message.content)

结果

```json
{
    "销售方名称": "湖北中基汽车销售服务有限公司",
    "购买方名称": "蔡应时",
    "不含税价": "230769.23",
    "组织机构代码": "",
    "发票代码": "142011726001"
}
```

4.第三方使用OpenAI库(如火山引擎-豆包)

  • 文本输入
    • OpenAI()方法的参数:
      • api_key:指定模型商提供的模型调用key
      • base_url:指定模型商提供的模型调用地址

代码

from openai import OpenAI
client = OpenAI(
    base_url="https://ark.cn-beijing.volces.com/api/v3",
    api_key="************",
)
response = client.chat.completions.create(
    # model="doubao-seed-1-6-flash-250615",
    model="doubao-seed-1-6-250615",
    messages=[
        {
            "role": "user",
            "content": "我要研究深度思考模型与非深度思考模型区别的课题",
        }
    ],
)
print(response.choices[0])

结果

Choice(
    finish_reason="stop",
    index=0,
    logprobs=None,
    message=ChatCompletionMessage(
        content="### 一、概念界定与理论...专业性与系统性。",
        refusal=None,
        role="assistant",
        annotations=None,
        audio=None,
        function_call=None,
        tool_calls=None,
        reasoning_content="用户现在需要研究深度思...和理论支撑。",
    ),
)
  • 图像输入
    • 多模态模型可以接收图片输入,并作出分析。

代码

from openai import OpenAI
client = OpenAI(
    base_url="https://ark.cn-beijing.volces.com/api/v3",
    api_key="************",
)
response = client.chat.completions.create(
    model="doubao-seed-1-6-250615",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://ark-project.tos-cn-beijing.ivolces.com/images/view.jpeg"
                    },
                },
                {"type": "text", "text": "这是哪里?"},
            ],
        }
    ],
)
print(response.choices[0])

结果

Choice(
    finish_reason="stop",
    index=0,
    logprobs=None,
    message=ChatCompletionMessage(
        content="这是一处典型的...与自然力量的交融之美。",
        refusal=None,
        role="assistant",
        annotations=None,
        audio=None,
        function_call=None,
        tool_calls=None,
        reasoning_content="\n用户现在问的是“这是哪里?”...观中的宁静与壮丽。",
    ),
)

总结

本文整理了 MinerU、BabelDOC、KTransformers 与 OpenAI API 库相关工具的使用方法,覆盖安装、配置、命令行调用、Python API 调用、模型加载、向量数据库操作、索引配置与运行结果等内容。实际使用时,建议根据硬件环境选择 CPU/GPU/NPU 加速方式,并将 API Key、Access Key、Secret Key 等敏感信息统一放入环境变量或配置文件中管理,避免直接写入代码。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐