Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable con

转载请注明出处:http://blog.youkuaiyun.com/dengbin9009/article/details/43485617

在使用AFNetworking 2.0  的时候本来一切很顺畅,但是中途遇到几个比较坑的地方

这里分享一下爬坑经历,忘读者不能速爬坑!

在发送请求后,NSURLSessionDataTask一直报错

Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html"

经过一番网上排查,网上有人说是AF2.0本身的问题,解析格式不全,所以需要在AF的源文件AFURLResponseSerialization.m中修改代码就能解决:

修改文件223行处

self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];

为:
self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];

即可!笔者试过确实可以,但是AF还在持续更新的类库,不宜随意修改,特别是在用了CocoaPods之后,如果之后更新库,此类错误又会重复出现,随后笔者发现acceptableContentTypes是一个开放的属性,既然这样,就证明acceptableContentTypes可以在外部被修改,所以可以在

初始化HttpClient单利的时候改变这一值:

- (instancetype)initWithBaseURL:(NSURL *)url {
    if (self = [super initWithBaseURL:url]) {
        
        self.responseSerializer = [AFJSONResponseSerializer serializer];
        self.requestSerializer.timeoutInterval = TimeoutInterval;
        self.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
        [self setHTTPHeader];  // 可在此处设置Http头信息
    }
    return self;
}


<think>我们正在处理一个TensorRT引擎反序列化错误,具体错误信息为: ``` Error Code 1: Serialization (Serialization assertion plan->header.magicTag==rt::kPLAN_MAGIC_TAG failed.) ``` 这个错误表明,当我们尝试加载一个TensorRT引擎文件(通常是以.engine或.plan为后缀的文件)时,文件头部的魔术标签(magic tag)与当前TensorRT运行时期望的魔术标签不匹配。魔术标签是一个用于标识文件类型的固定值,在这里是`rt::kPLAN_MAGIC_TAG`(其值为`0xBCFA5D18`,按小端序存储为`18 5D FA BC`)。 ### 错误原因分析 根据引用[1]和[2]提供的线索,我们可以推断以下可能的原因: 1. **TensorRT版本不兼容**(最常见原因)[^1] TensorRT引擎文件是高度依赖于特定版本的。如果你在一个版本的TensorRT(比如8.6.1)中生成引擎文件,然后尝试在另一个版本(比如7.2.3)中加载,就会出现魔术标签不匹配的错误。因为不同版本的TensorRT可能使用不同的魔术标签。 2. **引擎文件损坏** 文件在传输或存储过程中可能被损坏,导致文件头部的魔术标签被破坏。 3. **文件类型错误** 你可能错误地尝试加载了一个不是TensorRT引擎文件的文件(例如,一个ONNX模型文件或权重文件)。 4. **自定义插件未注册**(引用[2])[^2] 如果引擎中使用了自定义插件,那么在加载引擎时,必须确保这些插件已经被正确注册到TensorRT的插件注册表中。否则,在反序列化过程中会失败,并可能引发类似的错误(尽管这个错误通常会有不同的错误信息)。 ### 解决方案 #### ✅ 步骤1:验证引擎文件的完整性 首先,检查文件头部的魔术标签是否正确。可以使用以下命令(在Linux系统上): ```bash # 使用hexdump查看文件的前4个字节 hexdump -n 4 -C your_engine.engine ``` - 如果输出是`bc fa 5d 18`(小端序,即文件的前4个字节依次是0xBC, 0xFA, 0x5D, 0x18),那么魔术标签是正确的。 - 如果输出不是这个值,那么文件可能已损坏,或者根本不是一个TensorRT引擎文件。 #### ✅ 步骤2:检查TensorRT版本兼容性 确定生成引擎文件时使用的TensorRT版本和当前运行环境中的TensorRT版本是否一致。可以通过以下方式检查: ```python import tensorrt as trt print(trt.__version__) # 输出当前TensorRT版本 ``` 如果版本不一致,你有两个选择: 1. **在目标环境中重新生成引擎文件**(推荐) 使用当前环境中的TensorRT重新从ONNX(或其他格式)生成引擎文件。 2. **安装与生成引擎文件时相同版本的TensorRT** 如果你无法重新生成引擎文件(例如,引擎文件是由其他人提供的),那么你需要在当前环境中安装与生成引擎文件时相同的TensorRT版本。 #### ✅ 步骤3:重新生成引擎文件 如果版本不一致或者引擎文件损坏,重新生成引擎文件是最可靠的解决方案。以下是使用Python API重新生成引擎文件的示例代码: ```python import tensorrt as trt # 初始化TensorRT日志记录器 logger = trt.Logger(trt.Logger.WARNING) builder = trt.Builder(logger) # 创建网络定义 network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) parser = trt.OnnxParser(network, logger) # 加载ONNX模型 onnx_file_path = "your_model.onnx" with open(onnx_file_path, "rb") as f: if not parser.parse(f.read()): for error_idx in range(parser.num_errors): print(parser.get_error(error_idx)) raise RuntimeError("ONNX解析失败") # 配置构建选项 config = builder.create_builder_config() config.max_workspace_size = 1 << 30 # 1GB # 构建引擎 serialized_engine = builder.build_serialized_network(network, config) # 保存引擎文件 engine_file_path = "your_engine.engine" with open(engine_file_path, "wb") as f: f.write(serialized_engine) ``` #### ✅ 步骤4:处理自定义插件(如果适用) 如果引擎中使用了自定义插件,在加载引擎之前,必须确保这些插件已经注册到TensorRT的插件注册表中。通常,你需要: 1. 在代码中显式导入插件(Python): ```python import your_plugin_module # 这个模块中应该包含注册插件的代码 ``` 2. 或者,在C++中,你需要调用`initLibNvInferPlugins`函数并传递一个日志记录器,或者显式注册你的插件。 #### ✅ 步骤5:检查GPU架构兼容性 如果你在一种架构的GPU上生成引擎文件(例如,在RTX 3090上生成),然后在另一种架构的GPU上加载(例如,在Jetson Xavier上),即使TensorRT版本相同,也可能出现问题。确保生成引擎文件的目标GPU架构与运行环境一致。可以使用`trtexec`工具指定目标架构: ```bash trtexec --onnx=your_model.onnx --saveEngine=your_engine.engine --device=0 ``` ### 预防措施 1. **记录TensorRT版本** 在保存引擎文件的同时,记录生成该引擎文件的TensorRT版本,以便在部署时匹配。 2. **使用Docker容器** 使用Docker容器可以确保训练和部署环境的一致性,避免版本问题。 3. **校验文件哈希** 在传输引擎文件后,使用校验和(如MD5或SHA256)来验证文件完整性。 ### 错误排查流程图 ```mermaid graph TD A[遇到魔术标签错误] --> B{检查文件头} B --> |魔术标签正确| C[检查TensorRT版本] B --> |魔术标签错误| D[文件损坏或类型错误] D --> E[重新生成引擎文件] C --> |版本一致| F[检查自定义插件] C --> |版本不一致| G[重新生成引擎文件或更换TensorRT版本] F --> |有自定义插件| H[确保插件已注册] F --> |无自定义插件| I[检查GPU架构兼容性] H --> I I --> |不兼容| J[在目标GPU上重新生成] I --> |兼容| K[提交NVIDIA Issue] ``` ### 相关问题 1. 如何查看TensorRT引擎文件的内部版本号? 2. 在Jetson设备上如何安装特定版本的TensorRT? 3. TensorRT引擎文件头部的完整结构是什么? 4. 如何安全地跨平台迁移TensorRT引擎文件? [^1]: 引用[1]中提到了版本标签不匹配的错误(Current Version: 232 vs Serialized Engine Version: 205),这直接指向了版本兼容性问题。 [^2]: 引用[2]则指出,当引擎包含自定义插件时,如果插件未注册,也会导致反序列化失败。虽然错误信息略有不同,但也是需要检查的一个方面。</think>### TensorRT 反序列化错误:`plan->header.magicTag == rt::kPLAN_MAGIC_TAG failed` 分析与解决方案 #### 错误本质分析 此错误表明 TensorRT 引擎文件的**魔术标签(Magic Tag)验证失败**[^1][^2]。核心原因是引擎文件头部的特殊标识符 `0xBCFA5D18`(小端序)与当前 TensorRT 运行时期望的标识符不匹配,通常由以下原因导致: 1. **版本不兼容**(最常见) - 引擎文件在不同版本的 TensorRT 间迁移(如 TensorRT 7.x → 8.x) - 版本号冲突(如引用[1]所示:`Current Version: 232, Serialized Engine Version: 205`) 2. **文件损坏或类型错误** - 传输过程中损坏(如 FTP 未用二进制模式) - 误将 ONNX/权重文件当作引擎文件加载 3. **自定义插件问题**(如引用[2]所述) - 引擎包含自定义插件,但运行时未注册插件创建器 4. **GPU架构不兼容** - 在 Ampere 架构 GPU 生成的引擎在 Turing 架构设备加载 --- ### 系统级解决方案 #### ✅ 步骤1:验证引擎文件完整性 ```bash # 检查文件前4字节(Magic Tag 应为 0xBCFA5D18) hexdump -n 4 -C your_model.engine # 预期输出(小端序): 00000000 bc fa 5d 18 |..].| ``` - **若不匹配**:文件损坏 → 重新生成引擎 - **若匹配**:继续步骤2[^1] #### ✅ 步骤2:解决版本冲突(关键) ```bash # 查看当前 TensorRT 版本 python3 -c "import tensorrt as trt; print(trt.__version__)" # 卸载冲突版本(Ubuntu 示例) sudo apt purge libnvinfer* tensorrt* # 安装匹配版本(以 JetPack 5.1 为例) sudo apt install tensorrt=8.5.3-1+cuda11.8 ``` #### ✅ 步骤3:安全重建引擎(Python 示例) ```python import tensorrt as trt logger = trt.Logger(trt.Logger.WARNING) builder = trt.Builder(logger) network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) # 从 ONNX 重建(非引擎文件!) parser = trt.OnnxParser(network, logger) with open("model.onnx", "rb") as f: if not parser.parse(f.read()): for i in range(parser.num_errors): print("ONNX 解析错误:", parser.get_error(i)) # 生成新引擎 config = builder.create_builder_config() serialized_engine = builder.build_serialized_network(network, config) with open("new_model.engine", "wb") as f: f.write(serialized_engine) ``` #### ✅ 步骤4:处理自定义插件问题(如引用[2]) ```cpp // C++ 示例:注册自定义插件 #include "NvInferRuntime.h" #include "your_plugin_header.h" void loadEngineWithPlugins() { initLibNvInferPlugins(nullptr, ""); // 初始化内置插件 registerCustomPlugin(); // 注册自定义插件 // 然后加载引擎... } ``` #### ✅ 步骤5:GPU架构兼容性处理 ```bash # 使用 trtexec 指定目标架构 trtexec --onnx=model.onnx --saveEngine=model.engine \ --device=1 # 设备ID需匹配运行环境 ``` --- ### 预防措施 1. **版本锁定** 在 Dockerfile 中固定 TensorRT 版本: ```dockerfile FROM nvcr.io/nvidia/tensorrt:22.12-py3 ENV LD_LIBRARY_PATH=/usr/local/tensorrt/lib:$LD_LIBRARY_PATH ``` 2. **引擎文件校验工具** ```python def validate_engine(path): with open(path, "rb") as f: if f.read(4) != b'\xbc\xfa\x5d\x18': raise ValueError("引擎文件魔术标签损坏") f.seek(16) # 跳到版本信息偏移量 version = int.from_bytes(f.read(4), 'little') print(f"引擎内部版本: {version}") ``` 3. **跨设备迁移规范** - 生成引擎时记录 TensorRT 版本和 GPU 架构 - 使用 `tar -czvf` 打包避免传输损坏 --- ### 错误排查流程图 ```mermaid graph TD A[Magic Tag 错误] --> B{检查文件头} B -->|头损坏| C[重新生成引擎] B -->|头正常| D{检查序列化版本} D -->|版本不匹配| E[升级/降级 TensorRT] D -->|版本匹配| F[检查 GPU 架构] F -->|架构不兼容| G[在目标 GPU 重建] F -->|架构兼容| H[检查自定义插件] H -->|插件缺失| I[注册插件] H -->|无插件| J[提交 NVIDIA Issue] ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值