PySpark TrainValidationSplit搭配paramGrid是否每次重跑全流水线?
问题1解答
是的,该场景下默认每次参数遍历都会重跑完整流水线。Spark Pipeline本身没有内置中间结果缓存逻辑,TrainValidationSplit会为每一组参数完整执行所有stages,即便前序的索引器、编码器、VectorAssembler参数没有任何变化,也会重复执行。
问题2解答
有两种常用方案可以避免重复运行前序步骤:
- 手动拆分流水线预计算特征:将SVC以外的前序步骤单独封装为一个预处理Pipeline,先运行
pre_model = pre_pipeline.fit(train)得到预处理模型,再用pre_train = pre_model.transform(train).cache()得到预处理后的数据集并缓存,之后将单独的SVC作为estimator传入TrainValidationSplit,仅对SVC做参数搜索即可,前序步骤仅执行1次。 - 启用Spark Pipeline阶段缓存:如果你使用的是Spark 3.0及以上版本,可以直接给前序的每个stages设置存储级别,示例如下:
stringvar1_indexer.setCacheStorageLevel(StorageLevel.MEMORY_ONLY()) stringvar2_indexer.setCacheStorageLevel(StorageLevel.MEMORY_ONLY()) stringvar2_encoder.setCacheStorageLevel(StorageLevel.MEMORY_ONLY()) assembler.setCacheStorageLevel(StorageLevel.MEMORY_ONLY())
配置后Spark会自动缓存相同参数下的阶段输出,不需要手动拆分流水线即可避免重复计算。
问题3解答
拆分流水线后可以通过两种方法解决ONNX的向量输入兼容问题:
- 模型拼接:分别导出预处理Pipeline和最优SVC模型的ONNX格式文件,之后使用ONNX官方的图合并工具,将两个模型的计算图拼接为一个端到端的完整模型,最终导出的模型对外输入仍然是原始数据格式,不需要暴露向量输入,也不会出现不兼容问题。
- 显式声明输入类型:使用onnxmltools导出SVC模型时,手动配置
initial_types参数,指定向量输入的张量类型和维度,示例如下:
from onnxmltools.convert.common.data_types import FloatTensorType initial_types = [('features', FloatTensorType([None, 你的特征维度数]))] svc_onnx = convert_sparkml(svc_model, 'svc_model', initial_types)
配置后ONNX会将VectorUDT识别为对应维度的浮点张量,不再报错。
内容的提问来源于stack exchange,提问作者mwh
相关产品推荐
相关产品推荐

