ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Draco 顺序量化属性解码器(Sequential Quantization Attribute Decoder)深度解析:位流格式、反量化原理与源码实现

Draco 顺序量化属性解码器(Sequential Quantization Attribute Decoder)深度解析:位流格式、反量化原理与源码实现 图形学3D渲染【免费下载链接】dracoDraco is a library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.项目地址https://gitcode.com/gh_mirrors/draco1/draco点击查看免费下载本文以 Draco 项目规范文档 docs/spec/sequential.quantization.attribute.decoder.md 为主体完整解读顺序量化属性解码器的位流布局与反量化算法并结合 src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc 等源码实现展开纵深分析。读完本文你将掌握 Draco 中浮点属性位置、法线、纹理坐标等如何从量化后的整数还原为浮点数的完整流程、量化参数在比特流中的读写顺序以及DequantizeFloat反量化公式的数学本质。一、背景量化属性解码器在 Draco 中的定位Draco 通过顺序属性编码/解码器Sequential Attribute Encoder/Decoder处理点云与网格的属性数据。解码端由SequentialAttributeDecodersController根据比特流中读出的解码器类型号创建对应的顺序解码器类型号到解码器类的映射见 src/draco/compression/attributes/sequential_attribute_decoders_controller.ccSEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC→SequentialAttributeDecoder通用解码器SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER→SequentialIntegerAttributeDecoder整数解码器SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION→SequentialQuantizationAttributeDecoder量化解码器即本文主题SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS→SequentialNormalAttributeDecoder法线专用需DRACO_NORMAL_ENCODING_SUPPORTED宏开启。SequentialQuantizationAttributeDecoder继承自SequentialIntegerAttributeDecoder类声明见 src/draco/compression/attributes/sequential_quantization_attribute_decoder.h。它做的事情可以概括为一句话先用整数解码器把量化后的整数值从比特流中还原出来再把整数值通过反量化变换映射回浮点数区间并写回DT_FLOAT32类型的输出属性。量化只适用于浮点属性——Init()中检查属性数据类型必须为DT_FLOAT32否则返回false见 sequential_quantization_attribute_decoder.cc。二、位流格式量化参数的解析ParseQuantizationData / ParseQuantizationBits2.1 ParseQuantizationBits()读取量化位数规范文档给出的第一个流程函数ParseQuantizationBits()从比特流中读取一个UI8无符号 8 位整数作为量化位数存储到当前属性解码器/当前属性的槽位中void ParseQuantizationBits() { quantized_data_quantization_bits[curr_att_dec][curr_att] UI8 }2.2 ParseQuantizationData()读取完整的量化参数三元组ParseQuantizationData()是量化参数的入口函数它依次读取三部分数据void ParseQuantizationData() { num_components GetNumComponents(); for (j 0; j num_components; j) { quantized_data_min_values[curr_att_dec][curr_att][i] Float } quantized_data_max_value_df[curr_att_dec][curr_att] Float ParseQuantizationBits(); }即量化参数在比特流中的排列顺序为min_values每个分量一个Float各分量反量化后的最小值偏移量分量个数由GetNumComponents()决定max_value_df一个Float反量化后的值域范围源码中称为range_quantization_bits一个UI8量化位数。这一布局与编码端 src/draco/attributes/attribute_quantization_transform.cc 的EncodeParameters()严格对应先写全部min_values_sizeof(float) * num_components字节再写range_4 字节最后写quantization_bits1 字节uint8_t。解码端DecodeParameters()attribute_quantization_transform.cc按完全相同的顺序从DecoderBuffer中读出这三个参数并调用IsQuantizationValid()校验位数合法性。2.3 参数读取的时机比特流版本相关量化参数在比特流中的读取时机与 Draco 比特流版本bitstream version有关这是源码中的关键细节sequential_quantization_attribute_decoder.cc对比特流版本 ≥ 2.0的文件在DecodeDataNeededByPortableTransform()中调用DecodeQuantizedDataInfo()读取量化参数读取完成后通过quantization_transform_.TransferToAttribute(portable_attribute())把参数暂存到 portable attribute 的变换数据中对比特流版本 2.0的旧文件需编译时开启DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED则在DecodeIntegerValues()中先读取量化参数以兼容旧格式的布局。DecodeQuantizedDataInfo()的实现sequential_quantization_attribute_decoder.cc会优先取 portable attribute 作为参数解析的源属性在向后兼容模式下 portable attribute 可能为空此时回退到输出属性两者分量数一致不影响参数解析。三、反量化核心算法DequantizeFloat()3.1 规范文档中的公式规范文档给出的反量化单值函数DequantizeFloat()如下float DequantizeFloat(val, max_quantized_value_factor_, range_) { neg (val 0); if (neg) { val -val; } norm_value val * max_quantized_value_factor_; if (neg) norm_value -norm_value; return norm_value * range_; }其数学本质是把整数val除以最大量化值max_quantized_value归一化到[0, 1]区间再乘以值域range_映射回浮点数空间。其中max_quantized_value_factor_ 1.f / max_quantized_valuemax_quantized_value (1 quantization_bits) - 1。由于量化值可能为负数函数先取绝对值归一化、再恢复符号保证(-max_quantized_value, max_quantized_value)范围内的整数能正确映射到(-range_, range_)区间。3.2 源码中的等价实现DequantizeFloat在真实实现中被抽象为Dequantizer类见 src/draco/core/quantization_utils.h 与 src/draco/core/quantization_utils.ccbool Dequantizer::Init(float range, int32_t max_quantized_value) { if (max_quantized_value 0) { return false; } delta_ range / static_castfloat(max_quantized_value); return true; } inline float Dequantizer::DequantizeFloat(int32_t val) const { return static_castfloat(val) * delta_; }这里delta_ range_ / max_quantized_value就是两个相邻量化状态之间的浮点步长。把规范文档的两步计算合并val * (1/max_quantized_value) * range_ val * (range_/max_quantized_value) val * delta_两者完全等价。文档写法强调归一化 缩放两个阶段源码写法则直接预计算步长因子减少每次反量化的乘法开销——这是同一数学公式的两种工程表达。与之对称的量化器Quantizerquantization_utils.h则按inverse_delta_ max_quantized_value / range计算对浮点值val执行floor(val * inverse_delta_ 0.5f)即四舍五入到最近的整数位于两个量化状态正中间的值向上取整。量化与反量化构成一对可逆变换只是反量化无法恢复量化过程中丢弃的精度信息。四、主流程SequentialQuantizationAttributeDecoder_DequantizeValues()规范文档给出的主流程伪代码如下它串联起位流参数与反量化算法void SequentialQuantizationAttributeDecoder_DequantizeValues() { quantization_bits quantized_data_quantization_bits[curr_att_dec][curr_att]; max_quantized_value (1 (quantization_bits)) - 1; num_components GetNumComponents(); quant_val_id 0; range_ quantized_data_max_value_df[curr_att_dec][curr_att]; max_quantized_value_factor_ 1.f / max_quantized_value; min_value_ quantized_data_min_values[curr_att_dec][curr_att]; original_values seq_int_att_dec_original_values[curr_att_dec][curr_att]; num_values att_dec_num_values_to_decode[curr_att_dec][curr_att]; for (i 0; i num_values; i) { for (c 0; c num_components; c) { value DequantizeFloat(original_values[quant_val_id], max_quantized_value_factor_, range_); value value min_value_[c]; att_val[c] value; dequantized_data.push_back(value); } } seq_int_att_dec_dequantized_values[curr_att_dec][curr_att] dequantized_data; }逐段解读准备阶段从量化参数槽位取出quantization_bits计算max_quantized_value (1 quantization_bits) - 1即 2^bits − 1量化值域的最大整数取出range_与各分量min_value_[c]预计算max_quantized_value_factor_ 1.f / max_quantized_value。数据来源original_values指向顺序整数解码器已经还原出来的量化整数值序列seq_int_att_dec_original_valuesnum_values是待解码的属性值条目数由点序列数量决定。双重循环反量化外层遍历num_values个条目内层遍历num_components个分量。每个整数值经DequantizeFloat归一化缩放到(-range_, range_)区间再叠加该分量的最小值偏移min_value_[c]得到最终的浮点属性值依次写入att_val并追加进dequantized_data。结果落盘整段反量化结果保存到seq_int_att_dec_dequantized_values[curr_att_dec][curr_att]供后续写回目标属性。源码中的等价实现上述流程在真实源码中由SequentialQuantizationAttributeDecoder::DequantizeValues()sequential_quantization_attribute_decoder.cc委托给AttributeQuantizationTransform::InverseTransformAttribute()完成bool SequentialQuantizationAttributeDecoder::DequantizeValues( uint32_t num_values) { // Convert all quantized values back to floats. return quantization_transform_.InverseTransformAttribute( *GetPortableAttribute(), attribute()); }InverseTransformAttribute()的实现attribute_quantization_transform.cc与规范伪代码几乎一一对应校验目标属性数据类型必须为DT_FLOAT32计算max_quantized_value (1u quantization_bits_) - 1初始化Dequantizer(range_, max_quantized_value)把 portable attribute 的原始数据按int32_t视图读取量化值以 32 位整数存储双层循环value dequantizer.DequantizeFloat(source_attribute_data[quant_val_id]); value value min_values_[c];然后按sizeof(float) * num_components的条目大小写入目标属性的缓冲区。两者在算法上是同构的规范文档用max_quantized_value_factor_表达归一化源码用预计算的delta_规范文档把结果暂存到dequantized_data数组源码直接逐条目写入输出属性缓冲区。文档中min_value_与源码中min_values_都是逐分量的最小值数组range_max_value_df是所有分量中最大跨度的统一值域。五、与整数解码器的协作完整的解码链路顺序量化解码器是顺序整数解码器的子类因此完整的解码链路包含以下环节对照 src/draco/compression/attributes/sequential_integer_attribute_decoder.cc 与 sequential.quantization.attribute.decoder.md 的姊妹篇 sequential.integer.attribute.decoder.md解码预测方案DecodeValues()先从比特流读取 1 字节预测方案类型prediction_scheme_method若不为PREDICTION_NONE再读取预测变换类型当前只支持PREDICTION_TRANSFORM_WRAP变换sequential_integer_attribute_decoder.cc解码量化整数值DecodeIntegerValues()读取 1 字节compressed标志——若被压缩则用熵解码器DecodeSymbols()还原符号序列否则直接按每值num_bytes字节读取原始整数sequential_integer_attribute_decoder.cc符号转换与预测还原若预测值非正或未使用预测把无符号符号值ConvertSymbolsToSignedInts()转回带符号整数若存在预测方案则DecodePredictionData()后调用ComputeOriginalValues()重建原始整数值sequential.integer.attribute.decoder.md 中的ConvertSymbolToSignedInt/ConvertSymbolsToSignedInts/SequentialIntegerAttributeDecoder_DecodeIntegerValues即描述这一阶段反量化即本文第三节、第四节所述的DequantizeValues()流程把还原出的整数映射回浮点数。整条链路由SequentialAttributeDecodersController编排先生成点序列、解码 portable attributeDecodePortableAttributes、再解码 portable 变换所需数据DecodeDataNeededByPortableTransforms最后统一执行反变换TransformAttributesToOriginalFormat。其中还支持通过解码选项skip_attribute_transform跳过反变换直接用 portable attribute整数形式作为输出属性见 sequential_attribute_decoders_controller.cc——这对只需要整数属性值、不需要浮点精度的场景可以省去反量化开销。六、参数约束与编码端配置量化位数的合法范围6.1 量化位数合法性校验AttributeQuantizationTransform::IsQuantizationValid()明确限定量化位数范围attribute_quantization_transform.ccbool AttributeQuantizationTransform::IsQuantizationValid( int quantization_bits) { // Currently we allow only up to 30 bit quantization. return quantization_bits 1 quantization_bits 30; }因此quantization_bits的合法区间为[1, 30]。上限 30 而非 32是因为量化值以带符号 32 位整数存储且需保留符号位与居中语义max_quantized_value 2^bits − 1在 30 位时约为 10.7 亿已能覆盖绝大多数场景的精度需求。解码端在DecodeParameters()中也会用该校验拒绝非法位流。6.2 编码端对应的配置选项量化参数不是凭空写入比特流的它们由编码端决定。顺序量化编码器 src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc 从编码选项中读取配置quantization_bits整型默认-1量化位数 1时编码失败合法范围 1~30quantization_origin浮点向量长度等于属性分量数与quantization_range浮点默认1.f若两者都显式设置则直接作为min_values与range_写入比特流SetParameters若未显式设置 origin/range则ComputeParameters()扫描属性全部值逐分量求最小值作为min_values_取各分量max − min的最大差值作为range_若所有值相同导致range_ 0.f则回退为1.f确保仍可正确量化attribute_quantization_transform.cc。值得注意的是ComputeParameters遇到NaN/Inf值会直接返回false因此包含非有限值的浮点属性无法走量化路径。理解编码端配置有助于逆向读懂解码端比特流中的min_values就是编码时选择的quantization_origin或自动计算的最小值max_value_df/range_就是quantization_range或自动计算的跨度。实践中的压缩比调节正是通过调整quantization_bits完成的——位数越高量化步长delta_越小、精度越高、占用的熵编码符号空间越大位数越低量化误差越大、数据量越小。七、小结顺序量化属性解码器是 Draco 属性压缩体系中有损压缩的核心一环其完整技术要点可归纳为位流格式量化参数以min_values每分量Float→range_Float→quantization_bitsUI8的顺序写入/读出具体读取时机依赖比特流版本≥2.0 在 portable transform 阶段2.0 走向后兼容路径反量化公式float_value quantized_int * (range_ / ((1 quantization_bits) - 1)) min_values[c]等价于规范文档中DequantizeFloat()的归一化 缩放 偏移三步实现结构SequentialQuantizationAttributeDecoder继承自整数解码器量化参数与反量化逻辑封装在AttributeQuantizationTransform中逐点逐分量的标量运算最终由Dequantizer预计算delta_高效完成约束仅支持DT_FLOAT32属性量化位数限于 1~30 位非有限浮点值NaN/Inf会被拒绝。如需进一步了解前置的整数符号还原与预测解码阶段可继续阅读 docs/spec/sequential.integer.attribute.decoder.md若想从编码端理解量化参数的生成逻辑可对照 src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc 与 src/draco/attributes/attribute_quantization_transform.cc。赞分享图形学3D渲染【免费下载链接】dracoDraco is a library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.项目地址https://gitcode.com/gh_mirrors/draco1/draco点击查看免费下载相关推荐pytorch-quantization 函数式 API 深入解析ClipFunction 与 clip 的源码实现与量化实战pytorch quantization 函数式 API 深入解析ClipFunction 与 clip 的源码实现与量化实战 本篇文章以 NVIDIA Te人工智能推理引擎深度学习本地部署模型优化Prettier YAML 格式化保留 anchor 与 tag 的原始顺序含源码实现解析Prettier YAML 格式化保留 anchor 与 tag 的原始顺序含源码实现解析 本篇基于 Prettier 仓库中未发布的 YAML 变更记录开发工具格式化CLISpark-TTS源码解读核心模块FiniteScalarQuantization实现原理Spark TTS源码解读核心模块FiniteScalarQuantization实现原理 引言语音合成中的量化技术痛点与解决方案 在现代语音合成Text人工智能语音音频大模型模型推理服务上一篇数字创作革命开源平板驱动的跨平台艺术之旅下一篇H2O数据预处理技巧清洗、转换和特征工程的实用方法创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表