Spacy v3合并DocBin保存失败:字节对象过大问题求助
解决Spacy v3.0+中DocBin大文件保存"bytes object is too large"的问题
方法1:训练时直接指定多个DocBin文件(推荐)
不需要合并任何文件,直接在Spacy的训练配置文件config.cfg中指定多个训练数据路径即可。Spacy会自动加载并处理所有DocBin文件,完全规避大文件合并和保存的问题。
修改配置文件的[paths]部分:
[paths] train = ["G:\\success-demo\\product_ner\\test\\train3.spacy", "G:\\success-demo\\product_ner\\test\\train1.spacy", "G:\\success-demo\\product_ner\\test\\train2.spacy"] dev = "你的验证集文件路径"
之后直接运行spacy train config.cfg命令即可开始训练。
方法2:分块保存合并后的DocBin
如果确实需要保存合并后的数据集,可将合并后的DocBin按token数拆分为多个小文件,避免单个文件过大。
示例代码:
import spacy from spacy.tokens import DocBin # 加载对应语言的模型(用于获取词汇表) nlp = spacy.load("zh_core_web_sm") merged_doc_bin = DocBin() files = [ "G:\\success-demo\\product_ner\\test\\train3.spacy", "G:\\success-demo\\product_ner\\test\\train1.spacy", "G:\\success-demo\\product_ner\\test\\train2.spacy", ] # 合并所有DocBin for filename in files: doc_bin = DocBin().from_disk(filename) merged_doc_bin.merge(doc_bin) # 按每100万token拆分保存 docs = list(merged_doc_bin.get_docs(nlp.vocab)) chunk_token_limit = 1000000 current_tokens = 0 chunk_idx = 0 current_chunk = DocBin() for doc in docs: current_tokens += len(doc) current_chunk.add(doc) if current_tokens >= chunk_token_limit: chunk_path = f"G:\\success-demo\\product_ner\\test\\final\\merged_chunk_{chunk_idx}.spacy" current_chunk.to_disk(chunk_path) current_chunk = DocBin() current_tokens = 0 chunk_idx += 1 # 保存剩余的文档 if current_chunk.tokens > 0: final_chunk_path = f"G:\\success-demo\\product_ner\\test\\final\\merged_chunk_{chunk_idx}.spacy" current_chunk.to_disk(final_chunk_path)
拆分后的文件可在训练时通过配置文件的train列表全部指定,用法同方法1。
方法3:调整pickle序列化限制(不推荐)
该错误本质是pickle序列化单个bytes对象时超出默认限制,可修改pickle参数强制保存,但会生成超大文件,内存压力大,仅作备选方案。
示例代码:
import pickle from spacy.tokens import DocBin # 合并DocBin的代码不变 merged_doc_bin = DocBin() files = [ "G:\\success-demo\\product_ner\\test\\train3.spacy", "G:\\success-demo\\product_ner\\test\\train1.spacy", "G:\\success-demo\\product_ner\\test\\train2.spacy", ] for filename in files: doc_bin = DocBin().from_disk(filename) merged_doc_bin.merge(doc_bin) # 修改pickle参数保存 save_path = "G:\\success-demo\\product_ner\\test\\final\\merge.spacy" with open(save_path, "wb") as f: pickle.dump(merged_doc_bin.to_bytes(), f, protocol=4, fix_imports=True) # 加载时需对应调整参数 with open(save_path, "rb") as f: byte_data = pickle.load(f, fix_imports=True, encoding="bytes") loaded_doc_bin = DocBin().from_bytes(byte_data)
内容的提问来源于stack exchange,提问作者Rajesh Smartwebtech
相关产品推荐
相关产品推荐

