如何在Databricks上结合Spark NLP使用HuggingFace微调的NER模型
save_pretrained写入DBFS报错的解决方案
两种稳定可用的 workaround 可直接使用:
- 先写入Driver本地临时目录,再同步到DBFS
transformers原生支持本地文件系统写入,你可以先将模型存储到Driver节点的本地临时路径,再通过Databricks工具同步到DBFS目标路径,示例代码如下:
# 先保存到Driver本地临时路径 local_temp_path = "/tmp/finetuned_ner_model" model.save_pretrained(local_temp_path) tokenizer.save_pretrained(local_temp_path) # 递归移动到DBFS目标路径 dbutils.fs.mv(f"file:{local_temp_path}", "<你的DBFS存储路径>", recurse=True)
路径前加file:前缀是为了让dbutils识别为本地文件系统路径,避免默认读取DBFS路径报错。
- 直接使用DBFS Fuse挂载路径
Databricks所有节点默认会将DBFS挂载到本地/dbfs目录下,你直接将保存路径替换为/dbfs/开头的本地格式路径,transformers就会将其识别为普通本地路径完成写入,示例如下:
model.save_pretrained("/dbfs/your/custom/model/path")
该方案操作最简单,NER微调生成的模型体积较小,完全不会有性能问题。
纯Spark NLP实现自定义NER微调的方案
可以直接使用Spark NLP原生能力完成自定义NER Token分类器的微调,天然适配Databricks和DBFS,也支持你需要的仅标注格式训练:
- 数据格式兼容:原生支持CoNLL标注格式,你可以直接将数据库导出的实体标注转换为每行对应「token 标签」的格式,句子间用空行分隔,不需要额外补充其他特征,符合仅标注的要求。
- 端到端训练示例:
from sparknlp.annotator import * from sparknlp.base import * from pyspark.ml import Pipeline # 构建训练pipeline document_assembler = DocumentAssembler() \ .setInputCol("text") \ .setOutputCol("document") tokenizer = Tokenizer() \ .setInputCols(["document"]) \ .setOutputCol("token") # 加载预训练BERT嵌入,也可替换为你需要的其他预训练模型 bert_embeddings = BertEmbeddings.pretrained("bert_base_cased", "en") \ .setInputCols(["document", "token"]) \ .setOutputCol("embeddings") ner_trainer = BertForTokenClassification \ .pretrained() \ .setInputCols(["token", "embeddings"]) \ .setOutputCol("ner") \ .setLabelColumn("label") \ .setBatchSize(8) \ .setMaxEpochs(3) \ .setLr(2e-5) training_pipeline = Pipeline(stages=[document_assembler, tokenizer, bert_embeddings, ner_trainer]) # 训练完成后直接写入DBFS,完全兼容分布式文件系统 ner_model = training_pipeline.fit(train_dataset) ner_model.save("<直接写DBFS路径即可,无需额外前缀>")
该流程完全跑在Spark分布式集群上,大数据量场景下训练效率远高于单节点Hugging Face训练,也不需要额外适配Databricks运行环境。
内容的提问来源于stack exchange,提问作者Lord_JABA
相关产品推荐
相关产品推荐

