shuffle file cannot find错误

探讨Spark执行器堆外内存配置,解决大数据处理中常见的内存溢出及shuffle读写问题,介绍如何调整参数以提高任务稳定性。

Executor的堆外内存
Spark底层shuffle的传输方式是使用netty传输,netty在进行网络传输的过程会申请堆外内存(netty是零拷贝),所以使用了堆外内存。默认情况下,这个堆外内存上限默认是每一个executor的内存大小的10%;真正处理大数据的时候,这里都会出现问题,导致spark作业反复崩溃,无法运行;此时就会去调节这个参数,到至少1G(1024M),甚至说2G、4G。
executor在进行shuffle write,优先从自己本地关联的mapOutPutWorker中获取某份数据,如果本地block manager没有的话,那么会通过TransferService,去远程连接其他节点上executor的block manager去获取,尝试建立远程的网络连接,并且去拉取数据。频繁创建对象让JVM堆内存满溢,进行垃圾回收。正好碰到那个exeuctor的JVM在垃圾回收。处于垃圾回过程中,所有的工作线程全部停止;相当于只要一旦进行垃圾回收,spark / executor停止工作,无法提供响应,spark默认的网络连接的超时时长是60s;如果卡住60s都无法建立连接的话,那么这个task就失败了。task失败了就会出现shuffle file cannot find的错误。
那么如何调节等待的时长呢?
在./spark-submit提交任务的脚本里面添加:
–conf spark.core.connection.ack.wait.timeout=300
Executor由于内存不足或者堆外内存不足了,挂掉了,对应的Executor上面的block manager也挂掉了,找不到对应的shuffle map output文件,Reducer端不能够拉取数据。我们可以调节堆外内存的大小,如何调节?
在./spark-submit提交任务的脚本里面添加
yarn下:
–conf spark.yarn.executor.memoryOverhead=2048 单位M
standalone下:
–conf spark.executor.memoryOverhead=2048单位M

<think>我们遇到了两个关键问题: 1. TensorRT 无法找到插件 `InstanceNormalization_TRT version: 1`,导致引擎反序列化失败。 2. 引擎对象为 `None`,导致调用 `create_execution_context` 时出现 `AttributeError`。 ### 解决方案 #### 一、解决插件加载问题 **原因分析**: `InstanceNormalization` 操作在 TensorRT 中通常需要通过插件实现。错误信息表明 TensorRT 在插件注册表中找不到对应的插件创建器(Plugin Creator)。 **解决方法**: 1. **显式初始化插件注册表**(Python 环境): 在反序列化引擎之前,初始化 TensorRT 的内置插件: ```python import tensorrt as trt # 初始化所有内置插件(包括 InstanceNormalization) trt.init_libnvinfer_plugins(trt.Logger(trt.Logger.WARNING), "") ``` 注意:如果使用了自定义插件,需要加载对应的插件库。 2. **确保插件库可用**(C++ 环境): 在 C++ 代码中,添加以下代码: ```cpp #include "NvInferPlugin.h" // ... initLibNvInferPlugins(nullptr, ""); ``` 3. **验证插件是否注册**: 检查 TensorRT 是否包含 `InstanceNormalization` 插件: ```python registry = trt.get_plugin_registry() creator = registry.get_plugin_creator("InstanceNormalization_TRT", "1", "") if creator is None: print("错误:未找到 InstanceNormalization_TRT 插件") else: print("成功加载 InstanceNormalization_TRT 插件") ``` #### 二、解决引擎对象为 None 的问题 **原因分析**: 引擎构建失败(`builder.build_serialized_network()` 返回 `None`),通常由以下原因导致: - 模型包含 TensorRT 不支持的操作 - 插件未正确注册 - 输入/输出张量定义错误 - 工作空间内存不足 **解决方法**: 1. **启用详细日志**: 在构建引擎时启用详细日志,捕获具体错误信息: ```python logger = trt.Logger(trt.Logger.VERBOSE) # 使用 VERBOSE 级别 builder = trt.Builder(logger) config = builder.create_builder_config() config.set_flag(trt.BuilderFlag.VERBOSE) # 启用详细日志 ``` 2. **检查网络定义**: 验证所有层是否被 TensorRT 支持: ```python for i in range(network.num_layers): layer = network.get_layer(i) if not layer: continue if layer.type == trt.LayerType.SHUFFLE or layer.type == trt.LayerType.CONSTANT: # 检查这些层是否正确连接 pass # 打印层信息以便调试 print(f"层 {i}: 类型={layer.type}, 输入={layer.num_inputs}, 输出={layer.num_outputs}") ``` 3. **处理不支持的操作**: 如果模型包含 `Einsum` 等复杂操作,需要转换为 TensorRT 支持的等效操作序列,或使用插件实现。 4. **调整工作空间大小**: 限制工作空间大小以避免内存不足: ```python config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30) # 1GB ``` 5. **捕获并处理构建错误**: ```python try: serialized_engine = builder.build_serialized_network(network, config) if serialized_engine is None: raise RuntimeError("引擎构建失败:builder 返回 None") except Exception as e: # 打印日志中的错误信息 for i in range(logger.num_errors): error = logger.get_error(i) print(f"TensorRT 错误 {i}: {error}") ``` ### 完整代码示例 ```python import tensorrt as trt # 初始化插件 trt.init_libnvinfer_plugins(None, "") # 创建记录器 logger = trt.Logger(trt.Logger.VERBOSE) builder = trt.Builder(logger) network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) parser = trt.OnnxParser(network, logger) # 解析 ONNX 模型 with open("model.onnx", "rb") as f: if not parser.parse(f.read()): for error in range(parser.num_errors): print(parser.get_error(error)) # 配置构建器 config = builder.create_builder_config() config.set_flag(trt.BuilderFlag.FP16) # 可选:启用FP16 config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30) # 1GB config.set_flag(trt.BuilderFlag.VERBOSE) # 详细日志 # 构建引擎 try: serialized_engine = builder.build_serialized_network(network, config) if serialized_engine is None: raise RuntimeError("引擎构建失败:builder 返回 None") # 保存引擎 with open("engine.trt", "wb") as f: f.write(serialized_engine) # 创建执行上下文 runtime = trt.Runtime(logger) engine = runtime.deserialize_cuda_engine(serialized_engine) context = engine.create_execution_context() print("引擎构建成功!") except Exception as e: print(f"引擎构建失败: {str(e)}") # 打印所有错误日志 for i in range(logger.num_errors): print(f"错误详情 {i}: {logger.get_error(i)}") ``` ### 注意事项 1. **TensorRT 版本兼容性**:确保 TensorRT 版本与 CUDA、cuDNN 版本匹配。 2. **ONNX 模型优化**:在导出 ONNX 时,使用最新版本的 PyTorch 或 TensorFlow,并确保所有操作都支持。 3. **自定义插件**:如果 `InstanceNormalization` 仍然无法加载,可能需要手动编译并注册插件库。 通过以上步骤,应该能够解决插件加载失败和引擎构建问题。如果问题仍然存在,请检查 TensorRT 插件库的完整性和版本兼容性。 §§相关问题§§ 1. 如何编译 TensorRT 自定义插件? 2. TensorRT 支持哪些 ONNX 算子? 3. 如何将 Einsum 操作转换为 TensorRT 支持的等效操作? </think> ### 解决 TensorRT 插件加载与引擎构建失败问题 您遇到的 `getPluginCreator could not find plugin: InstanceNormalization_TRT version: 1` 和 `'NoneType' object has no attribute 'create_execution_context'` 是两个相互关联的问题,以下是完整的解决方案: --- ### 一、解决插件加载问题 #### 原因分析 `InstanceNormalization_TRT` 是 TensorRT 的内置插件,但需要手动初始化才能注册到插件注册表[^2]。 #### 解决方案 在**引擎反序列化前**添加插件初始化代码: **Python 解决方案**: ```python import tensorrt as trt # 关键步骤:初始化内置插件 trt.init_libnvinfer_plugins(None, "") # 空字符串表示加载所有内置插件 # 然后进行引擎反序列化 with open("model.engine", "rb") as f: runtime = trt.Runtime(trt.Logger(trt.Logger.WARNING)) engine = runtime.deserialize_cuda_engine(f.read()) # 现在能正确识别InstanceNormalization ``` **C++ 解决方案**: ```cpp #include <NvInfer.h> #include <NvInferPlugin.h> // 关键头文件 int main() { // 初始化插件注册表 initLibNvInferPlugins(nullptr, ""); // 然后进行引擎反序列化 nvinfer1::IRuntime* runtime = nvinfer1::createInferRuntime(logger); nvinfer1::ICudaEngine* engine = runtime->deserializeCudaEngine(engineData.data(), engineSize); } ``` --- ### 二、解决引擎对象为 None 的问题 #### 原因分析 引擎构建失败(`builder.build_serialized_network()` 返回 `None`),通常由以下原因导致: 1. 模型包含不支持的操作(即使已添加插件初始化) 2. 工作空间内存不足 3. 输入/输出张量定义错误 #### 解决方案 ```python logger = trt.Logger(trt.Logger.VERBOSE) # 使用详细日志 builder = trt.Builder(logger) config = builder.create_builder_config() # 关键配置调整 config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30) # 1GB工作空间 config.set_flag(trt.BuilderFlag.VERBOSE) # 启用详细日志 try: # 构建引擎前再次确认插件初始化 trt.init_libnvinfer_plugins(None, "") serialized_engine = builder.build_serialized_network(network, config) if serialized_engine is None: # 提取详细错误信息 for i in range(logger.num_errors): err = logger.get_error(i) print(f"TensorRT Error {i}: {err}") raise RuntimeError("引擎构建失败") except Exception as e: print(f"构建错误: {str(e)}") ``` --- ### 三、终极解决方案:完整工作流 ```mermaid graph TD A[加载ONNX模型] --> B[初始化插件] B --> C[创建TensorRT网络] C --> D[配置构建参数] D --> E{构建引擎} E -->|成功| F[序列化引擎] E -->|失败| G[分析详细日志] G --> H[调整模型/配置] H --> C F --> I[反序列化引擎] I --> J[创建执行上下文] ``` 具体代码实现: ```python def build_engine(onnx_path): # 1. 初始化 trt.init_libnvinfer_plugins(None, "") logger = trt.Logger(trt.Logger.VERBOSE) builder = trt.Builder(logger) # 2. 创建网络 network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) parser = trt.OnnxParser(network, logger) # 3. 解析ONNX with open(onnx_path, "rb") as model: if not parser.parse(model.read()): for i in range(parser.num_errors): print(parser.get_error(i)) return None # 4. 配置构建器 config = builder.create_builder_config() config.max_workspace_size = 1 << 30 # 1GB config.set_flag(trt.BuilderFlag.FP16) # 可选 # 5. 构建引擎 try: engine = builder.build_engine(network, config) if not engine: print("引擎构建返回None") return None # 6. 序列化保存 with open("engine.trt", "wb") as f: f.write(engine.serialize()) return engine except Exception as e: print(f"构建异常: {str(e)}") # 打印所有TRT错误 for i in range(logger.num_errors): print(f"TRT Error {i}: {logger.get_error(i)}") return None # 使用示例 engine = build_engine("model.onnx") if engine: context = engine.create_execution_context() # 现在不会出现NoneType错误 ``` --- ### 常见问题排查表 | 现象 | 可能原因 | 解决方案 | |------|---------|----------| | 插件未找到 | 未初始化插件 | 添加 `trt.init_libnvinfer_plugins(None, "")` | | 引擎构建返回None | 工作空间不足 | 增加 `config.max_workspace_size` | | 特定层不支持 | 模型包含非常规操作 | 使用ONNX Simplifier简化模型 | | 内存错误 | GPU内存不足 | 减小批量大小或输入分辨率 | > **关键提示**:如果问题仍未解决,尝试使用 TensorRT 的 `trtexec` 工具进行独立验证: > ```bash > trtexec --onnx=model.onnx --verbose --plugins=libnvinfer_plugin.so > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值