
NLP人工智能【免费下载链接】pkuseg-pythonpkuseg多领域中文分词工具; The pkuseg toolkit for multi-domain Chinese word segmentation项目地址https://gitcode.com/gh_mirrors/pk/pkuseg-python点击查看免费下载pkusegpkuseg-python在文件级分词pkuseg.test与训练阶段均内置了基于multiprocessing的多进程实现可通过nthread参数开启。本文以仓库文档 readme/multiprocess.md 为核心系统讲解将代码写入脚本文件时如何正确调用多进程接口、为什么必须用if __name__ __main__保护顶层语句否则会触发RuntimeError/BrokenPipeError并解释 Windows 平台上文件足够大时再使用多进程背后的进程启动开销原理。读完本文你将能写出可复跑、跨平台稳定的 pkuseg 多进程分词与训练脚本。一、多进程入口nthread参数在哪些接口生效pkuseg 的多进程能力并非作用于逐句分词pkuseg.pkuseg(...).cut(...)永远是单进程推理而是集中在以下两个文件级接口文件分词pkuseg.test对输入文件逐行分词并写回输出文件nthread控制进程数模型训练pkuseg.train训练过程中的测试集解码支持多进程由训练配置nThread控制。pkuseg.test的完整签名来自当前仓库源码pkuseg/init.py 中test函数的实际签名为def test( input_file, output_file, model_namedefault, user_dictdefault, nthread10, postagFalse, verboseFalse, ):各参数说明参数默认值含义input_file无必填输入文件路径需存在否则抛出input_file ... does not exist异常output_file无必填输出文件路径结果按行写入model_namedefault模型路径或领域名default/news/web/medicine/tourism同pkuseg.pkuseguser_dictdefault用户词典路径同pkuseg.pkusegnthread10测试时开启的进程数postagFalse是否同时进行词性标注verboseFalse是否打印各阶段耗时明细关键逻辑pkuseg/init.py当nthread 1时走_test_multi_proc多进程路径nthread为 1 或更小时退化为_test_single_proc单进程路径。因此nthread1是一个天然的关闭多进程开关便于调试对比。pkuseg.train的签名def train(trainFile, testFile, savedir, train_iter20, init_modelNone):从当前仓库源码看pkuseg/init.pytrain函数本身并不接收nthread参数其内部会把config.nThread强制置为 1config.nThread 1。需要说明的是readme/multiprocess.md 的示例中出现了pkuseg.train(..., nthread20)的写法这与当前仓库的实际签名不一致直接照抄会因多余的关键字参数报TypeError。训练阶段的进程数由训练器内部的解码配置config.nThread决定详见下文第四节多进程主要在pkuseg.test上发挥提速作用。二、脚本化运行多进程if __name__ __main__保护是硬性要求readme/multiprocess.md 明确指出当把代码示例写入文件运行时凡是涉及多进程功能务必使用if __name__ __main__保护全局语句。原文档给出的标准写法mp.py文件import pkuseg if __name__ __main__: pkuseg.test(input.txt, output.txt, nthread20) pkuseg.train(msr_training.utf8, msr_test_gold.utf8, ./models, nthread20)运行方式python3 mp.py注意如上文所述当前仓库的pkuseg.train签名不含nthread参数若照抄示例中的训练调用需去掉nthread20即pkuseg.train(msr_training.utf8, msr_test_gold.utf8, ./models)训练轮数可通过train_iter指定。为什么缺少保护会报RuntimeError和BrokenPipeError这背后是 Pythonmultiprocessing的进程启动机制问题pkuseg 在 pkuseg/init.py 的_test_multi_proc中直接使用了标准库multiprocessingfrom multiprocessing import Process, Queue ... in_queue Queue() out_queue Queue() procs [] for _ in range(nthread): p Process(target_proc, args(seg, in_queue, out_queue)) procs.append(p)在spawnWindows 默认、macOS 默认启动方式下Process会以重新导入主模块的方式初始化子进程。如果没有if __name__ __main__保护子进程在导入mp.py时又会把pkuseg.test(...)执行一遍从而递归地创建新的进程最终导致无限递归创建进程 → 抛出RuntimeError如 cannot start a process again管道/队列通信在异常终止下写入失败 → 抛出BrokenPipeError。加上if __name__ __main__保护后子进程在重新导入主模块时只会执行import pkuseg这一层而不会再次触发任务入口进程按预期各司其职。这是所有把多进程代码写进脚本文件的 pkuseg 用户的必备规范。三、源码视角多进程分词的任务流水线_test_multi_procpkuseg/init.py的实现体现了经典的生产者-消费者模型整体流程为加载模型仅主进程fork 模式seg pkuseg(model_name, user_dict, postag)模型只加载一份读取文件主进程readlines()读入全部文本行创建任务队列in_queue行索引 文本行、out_queue行索引 分词结果进程数 nthread投递任务将(idx, line)全部放入in_queue随后为每个子进程放入None哨兵作为结束信号启动子进程子进程循环从in_queue取行调用seg.cut(line)分词后把结果放回out_queue收集结果主进程按行索引回填result[idx]保证输出顺序与输入一致收尾join()等待全部子进程退出最后按行写回输出文件。子进程的工作函数_proc如下pkuseg/init.pydef _proc(seg, in_queue, out_queue): while True: item in_queue.get() if item is None: return idx, line item if not seg.postag: output_str .join(seg.cut(line)) else: output_str .join(map(lambda x:/.join(x), seg.cut(line))) out_queue.put((idx, output_str))值得注意的一个实现细节pkuseg 会检测当前的启动方式——alt multiprocessing.get_start_method() spawnpkuseg/init.py。在 spawn 模式下模型不再由主进程加载后序列化传给子进程fork 模式才可安全继承而是改用_proc_alt让每个子进程各自加载一份模型def _proc_alt(model_name, user_dict, postag, in_queue, out_queue): seg pkuseg(model_name, user_dict, postagpostag) while True: item in_queue.get() ...这就是 Windows 上多进程分词行为与 Linux 存在差异的根源见第四节。用verboseTrue观察各阶段耗时_test_multi_proc支持verboseTrue会打印如下阶段耗时单位秒load_model read_file start_proc word_seg join_proc write_file在 spawn 模式下阶段表会相应调整省略load_model合并为load_modal word_seg模型加载被摊入子进程分词阶段。利用该输出你可以定量判断多进程是否真的更快、开销花在了哪里为是否开启多进程提供依据。四、Windows 平台文件足够大时再使用多进程readme/multiprocess.md 第二条注意事项为在 Windows 平台上请当文件足够大时再使用多进程分词功能。结合上文源码可以给出底层解释Windows 上multiprocessing默认使用spawn启动方式每个子进程都要重新导入主模块并执行_proc_alt中的seg pkuseg(...)即每个进程独立加载一份分词模型模型加载本身耗时且占用内存进程创建、模块导入、模型加载这些一次性开销都发生在真正分词之前。若待处理文件很小、行数少这些固定开销远超并行分词的收益出现开了多进程反而更慢的现象反之当文件足够大行数多、每行文本长时分词计算量成为主导nthread个进程并行处理能摊薄启动开销体现出提速效果。同样的道理也适用于 Linux/macOS 上的 fork 模式只是 fork 模式子进程通过内存继承共享已加载的模型启动开销小得多因此对文件大小的敏感度较低。此外训练阶段的多进程同样遵循该原则Trainer._decode_multi_procpkuseg/trainer.py会按config.nThread创建子进程通过Queue分发测试集样本的特征做 Viterbi 解码config.nThread的默认值为 10见 pkuseg/config.py。多进程只发生在训练中每次迭代的测试集评测环节且由于该环节同样是固定进程开销 逐样本解码小规模数据下收益有限。五、一份可复用的跨平台多进程分词脚本模板综合原文档规范与当前仓库源码推荐按以下模板编写脚本以分词为例import pkuseg if __name__ __main__: # 输入文件必须存在否则抛出异常 pkuseg.test( input.txt, # 输入文件 output.txt, # 输出文件 model_namedefault, # 模型default / news / web / medicine / tourism 或模型路径 user_dictdefault, # 用户词典default / None / 自定义词典路径 nthread20, # 进程数1 时启用多进程文件较小时建议设 1 postagFalse, # 是否词性标注 verboseFalse, # 是否打印各阶段耗时 )要点回顾任何脚本化调用无论test还是train都必须包在if __name__ __main__:内避免 spawn 模式下递归创建进程引发RuntimeError/BrokenPipeErrornthread默认 10nthread1即单进程模式可作对照实验Windows 上小文件慎开多进程——每个子进程都要重新加载模型固定开销大文件足够大时收益才明显交互式环境如 Jupyter / python REPL中没有重导入主模块问题但将代码落盘为脚本运行时必须遵守上述规范。有关多进程分词问题的 FAQ 条目可对照查看仓库根目录 README.md 的常见问题及解答部分其中第 3 条无法使用多进程分词和训练功能提示RuntimeError和BrokenPipeError与第 9 条关于多进程速度问题与本文主题直接对应pkuseg.test多进程调用的入门示例另见 readme/interface.md 的代码示例 4。赞分享NLP人工智能【免费下载链接】pkuseg-pythonpkuseg多领域中文分词工具; The pkuseg toolkit for multi-domain Chinese word segmentation项目地址https://gitcode.com/gh_mirrors/pk/pkuseg-python点击查看免费下载相关推荐30 Seconds of Python彻底搞懂 if __name__ __main__ 的作用与正确用法30 Seconds of Python彻底搞懂 if __name__ __main__ 的作用与正确用法 if __name__ __m教程文档深入理解 CPython 中的 __main__顶层代码环境、python -m 执行与 if __name__ __main__ 惯用法全解深入理解 CPython 中的 __main__ 顶层代码环境、 python m 执行与 if __name__ __main__ 惯用法全解 _编程语言语言运行时解释器标准库python-mastery 课程实战用 if __name__ __main__ 守卫把 Python 脚本改造成可复用模块Exercise 1.6 详解python mastery 课程实战用 if __name__ __main__ 守卫把 Python 脚本改造成可复用模块Exercise 1示例工程教程上一篇X6图形导出为图片Canvas渲染终极解决方案 下一篇RediSQL核心功能解析如何用Redis模块实现高效SQL操作创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考