<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>AI on File Format Blog</title>
    <link>https://blog.fileformat.com/zh/categories/ai/</link>
    <description>Recent content in AI on File Format Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh</language>
    <lastBuildDate>Thu, 21 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.fileformat.com/zh/categories/ai/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>如何为 AI 训练和多模态 LLM 准备数据文件格式</title>
      <link>https://blog.fileformat.com/zh/file-formats/how-to-prepare-data-file-formats-for-ai-training-and-multi-modal-llms/</link>
      <pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate>
      
      <guid>https://blog.fileformat.com/zh/file-formats/how-to-prepare-data-file-formats-for-ai-training-and-multi-modal-llms/</guid>
      <description>通过合适的流式就绪、列式二进制格式（TFRecord、WebDataset、Arrow），提升 AI 训练速度 30‑50%，并降低存储成本。</description>
      <content:encoded><![CDATA[<p><strong>Last Updated</strong>: 21 May, 2025</p>
<figure class="align-center ">
    <img loading="lazy" src="images/how-to-prepare-data-file-formats-for-ai-training.webp#center"
         alt="标题 - 如何为 AI 训练和多模态 LLM 准备数据文件格式"/> 
</figure>

<p><strong>TL;DR</strong> – 您选择的文件格式可以削减 <strong>30‑50 %</strong> 的训练时间，降低 <strong>1 %–5 %</strong> 的存储成本，并防止多模态模型因数据不对齐而出错。最佳方案是 <strong>流式就绪、列式二进制容器</strong>（TFRecord、WebDataset、Arrow/Parquet），在单个受版本控制的分片中存储 <strong>预分词文本</strong> 和 <strong>预编码媒体</strong>。</p>
<hr>
<h2 id="为何文件格式对-ai-训练至关重要">为何文件格式对 AI 训练至关重要</h2>
<table>
<thead>
<tr>
<th>事实</th>
<th>对你的意义</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>二进制、列式格式比 CSV 或纯文本快 30‑50 %</strong></td>
<td>选择直接与硬件（GPU/TPU）和管道（TensorFlow、PyTorch、Spark）对接的格式。</td>
</tr>
<tr>
<td><strong>不一致的分词或图像解码会损害模型质量</strong></td>
<td>一次冻结预处理管道，然后存储<em>已分词</em>或<em>已编码</em>的表示。</td>
</tr>
<tr>
<td><strong>PB 级别的 LLM 通过 1 % 的尺寸缩减可节省数百万美元</strong></td>
<td>使用压缩、分片的容器（ZSTD‑TFRecord、Arrow/Parquet 带字典编码）。</td>
</tr>
<tr>
<td><strong>多模态模型需要同步的对齐元数据</strong></td>
<td>将时间戳、边界框、字幕 ID <strong>保存在同一记录</strong>中，而不是分散在不同文件里。</td>
</tr>
<tr>
<td><strong>监管合规现在要求不可变、哈希校验的数据</strong></td>
<td>生成一个清单（JSON/YAML），记录模式、校验和、来源和版本。</td>
</tr>
</tbody>
</table>
<p>底线：<strong>格式是防止 I/O 缓慢、数据噪声和合规麻烦的第一道防线</strong>。</p>
<hr>
<h2 id="核心概念与术语快速参考">核心概念与术语（快速参考）</h2>
<table>
<thead>
<tr>
<th>概念</th>
<th>一句话定义</th>
<th>典型使用场景</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Sharding</strong></td>
<td>将海量数据集拆分为许多小的、可独立读取的文件（例如 1 GB 分片）。</td>
<td>在分布式训练集群上并行加载。</td>
</tr>
<tr>
<td><strong>Streaming‑Ready Format</strong></td>
<td>能够顺序读取而无需随机寻址的文件（TFRecord、WebDataset <code>.tar</code>）。</td>
<td>直接从 S3/GCS 进行训练，无需本地副本。</td>
</tr>
<tr>
<td><strong>Columnar Storage</strong></td>
<td>按列而非按行存储数据（Parquet、Arrow）。</td>
<td>高效过滤单一模态（例如仅加载字幕）。</td>
</tr>
<tr>
<td><strong>Self‑Describing Schema</strong></td>
<td>文件内部嵌入字段名称和类型。</td>
<td>保证跨代码版本的兼容性。</td>
</tr>
<tr>
<td><strong>Lazy Decoding / Pre‑Tokenization</strong></td>
<td>存储已分词的文本（int‑IDs）或预计算的嵌入。</td>
<td>将预处理时间在每个 epoch 中降低 2‑5×。</td>
</tr>
<tr>
<td><strong>Multi‑Modal Record</strong></td>
<td>将图像、文本、音频和元数据打包为一个逻辑记录。</td>
<td>为视觉‑语言或音频‑文本模型提供同步抽样。</td>
</tr>
<tr>
<td><strong>Manifest / Index File</strong></td>
<td>列出所有分片、校验和及每个分片统计信息的小型 JSON/YAML。</td>
<td>快速验证、可恢复训练、审计追踪。</td>
</tr>
<tr>
<td><strong>Data‑Versioning</strong></td>
<td>将数据视作代码进行管理（DVC、LakeFS、Pachyderm）。</td>
<td>实验可复现并满足监管合规。</td>
</tr>
</tbody>
</table>
<hr>
<h2 id="选择合适的格式">选择合适的格式</h2>
<table>
<thead>
<tr>
<th>格式</th>
<th>模态支持</th>
<th>压缩</th>
<th>流式读取</th>
<th>模式</th>
<th>生态系统</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>TFRecord</strong></td>
<td>任意二进制 Blob → 文本、图像、音频</td>
<td>内置 GZIP/ZSTD</td>
<td>✅</td>
<td>隐式（通过 <code>tf.io.parse_example</code>）</td>
<td>TensorFlow、PyTorch（<code>torchdata</code>）、HuggingFace <code>datasets</code></td>
</tr>
<tr>
<td><strong>WebDataset</strong> (<code>.tar</code>, <code>.tar.gz</code>)</td>
<td>多模态（图像 + 文本 + 音频）</td>
<td>外部（gzip、zstd）</td>
<td>✅</td>
<td>隐式键值对</td>
<td>PyTorch DataLoader、<code>webdataset</code> 库</td>
</tr>
<tr>
<td><strong>Apache Arrow / Parquet</strong></td>
<td>列式、嵌套结构、二进制 Blob</td>
<td>Snappy/ZSTD/LZ4</td>
<td>✅（Arrow Flight）</td>
<td>✅（自描述）</td>
<td>Spark、Pandas、PyArrow、HuggingFace <code>datasets</code></td>
</tr>
<tr>
<td><strong>JSONL / NDJSON</strong></td>
<td>人类可读、灵活</td>
<td>无（或 gzip）</td>
<td>❌</td>
<td>隐式</td>
<td>快速原型、小规模数据集</td>
</tr>
<tr>
<td><strong>LMDB</strong></td>
<td>快速随机读取（键值对）</td>
<td>无（存储压缩 Blob）</td>
<td>❌</td>
<td>隐式</td>
<td>检索增强生成</td>
</tr>
<tr>
<td><strong>HDF5</strong></td>
<td>分层组、大型数组</td>
<td>内置 gzip/lzf</td>
<td>❌（需分块）</td>
<td>隐式</td>
<td>科学数据、音频频谱图</td>
</tr>
</tbody>
</table>
<p><strong>经验法则：</strong></p>
<ul>
<li><strong>大规模训练 → TFRecord、WebDataset 或 Arrow/Parquet</strong>（支持流式、压缩、分片）。</li>
<li><strong>探索性工作 → JSONL</strong>（人类可读、易编辑）。</li>
<li><strong>重随机访问（如检索增强生成） → LMDB</strong>。</li>
</ul>
<hr>
<h2 id="步骤蓝图从原始文件到生产就绪的分片">步骤蓝图（从原始文件到生产就绪的分片）</h2>
<ol>
<li>
<p><strong>定义唯一的真相模式</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-proto" data-lang="proto"><span style="display:flex;"><span><span style="color:#66d9ef">message</span> <span style="color:#a6e22e">MultiModalExample</span> {<span style="color:#960050;background-color:#1e0010">
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span>  <span style="color:#66d9ef">bytes</span> image <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>;                <span style="color:#75715e">// JPEG‑XL or AVIF
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>  <span style="color:#66d9ef">repeated</span> <span style="color:#66d9ef">int32</span> caption <span style="color:#f92672">=</span> <span style="color:#ae81ff">2</span>;    <span style="color:#75715e">// token IDs
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>  <span style="color:#66d9ef">bytes</span> audio <span style="color:#f92672">=</span> <span style="color:#ae81ff">3</span>;                <span style="color:#75715e">// Opus or FLAC
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>  map&lt;<span style="color:#66d9ef">string</span>, <span style="color:#66d9ef">string</span>&gt; meta <span style="color:#f92672">=</span> <span style="color:#ae81ff">4</span>;  <span style="color:#75715e">// source_id, timestamp, etc.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>}<span style="color:#960050;background-color:#1e0010">
</span></span></span></code></pre></div><p>将此 <code>.proto</code>（或 Arrow 模式）与数据集一起保存。</p>
</li>
<li>
<p><strong>收集并清洗原始资产</strong></p>
<ul>
<li><strong>文本：</strong> Unicode‑NFKC，去除控制字符，去重。</li>
<li><strong>图像：</strong> 先转为无损 PNG，再可选转为有损 JPEG‑XL（质量 85‑90 %）。</li>
<li><strong>音频：</strong> 重采样至 16 kHz、16‑bit PCM；使用 Opus（有损）或 FLAC（无损）编码。</li>
</ul>
</li>
<li>
<p><strong>预处理 / 分词</strong><br>
使用模型实际使用的分词器（例如 <code>tiktoken</code> 用于 GPT‑NeoX）。将得到的 <code>int32[]</code> token ID 直接写入记录。</p>
</li>
<li>
<p><strong>序列化每条记录</strong><br>
选用高速二进制序列化器：Protocol Buffers、FlatBuffers 或 Arrow IPC。目标是 <strong>每个示例对应单个字节串</strong>，可写入 TFRecord 或 tar 包。</p>
</li>
<li>
<p><strong>分片并压缩</strong></p>
<ul>
<li>目标分片大小：<strong>256 MiB – 1 GiB</strong>（对 S3 GET range 请求最优）。</li>
<li>使用 <strong>Zstandard（level 3‑5）</strong> 进行压缩——解压快、压缩率好。</li>
<li>命名规范：<code>train-00000-of-01000.tfrecord.zst</code>。</li>
</ul>
</li>
<li>
<p><strong>生成清单</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>[
</span></span><span style="display:flex;"><span>  {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;shard&#34;</span>: <span style="color:#e6db74">&#34;train-00000-of-01000.tfrecord.zst&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;checksum&#34;</span>: <span style="color:#e6db74">&#34;sha256:ab12…&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;num_examples&#34;</span>: <span style="color:#ae81ff">12456</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;avg_seq_len&#34;</span>: <span style="color:#ae81ff">256</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;git_hash&#34;</span>: <span style="color:#e6db74">&#34;d3f9c1e&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#960050;background-color:#1e0010">…</span>
</span></span><span style="display:flex;"><span>]
</span></span></code></pre></div><p>清单是验证、可恢复训练和审计的唯一真相来源。</p>
</li>
<li>
<p><strong>验证</strong><br>
随机抽样 0.1 % 的记录，解码每个字段并执行检查（图像解码、token 长度、音频时长）。计算全局统计（词表覆盖、分辨率分布），并写入清单。</p>
</li>
<li>
<p><strong>版本化并以不可变方式存储</strong><br>
将分片 + 清单推送至不可变桶（<code>gs://my‑project/datasets/v1/</code>）。使用语义版本标记（<code>v1.0.0</code>），并在数据版本管理系统（DVC、LakeFS）中登记快照。</p>
</li>
<li>
<p><strong>在训练循环中加载</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># PyTorch + WebDataset example</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> webdataset <span style="color:#66d9ef">as</span> wds<span style="color:#f92672">,</span> torch<span style="color:#f92672">,</span> torchvision<span style="color:#f92672">,</span> torchaudio
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">decode</span>(sample):
</span></span><span style="display:flex;"><span>    img <span style="color:#f92672">=</span> torchvision<span style="color:#f92672">.</span>io<span style="color:#f92672">.</span>decode_image(sample[<span style="color:#e6db74">&#34;jpg&#34;</span>], mode<span style="color:#f92672">=</span>torchvision<span style="color:#f92672">.</span>io<span style="color:#f92672">.</span>ImageReadMode<span style="color:#f92672">.</span>RGB)
</span></span><span style="display:flex;"><span>    txt <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>tensor([int(t) <span style="color:#66d9ef">for</span> t <span style="color:#f92672">in</span> sample[<span style="color:#e6db74">&#34;txt&#34;</span>]<span style="color:#f92672">.</span>decode()<span style="color:#f92672">.</span>split()], dtype<span style="color:#f92672">=</span>torch<span style="color:#f92672">.</span>long)
</span></span><span style="display:flex;"><span>    wav, _ <span style="color:#f92672">=</span> torchaudio<span style="color:#f92672">.</span>load(io<span style="color:#f92672">.</span>BytesIO(sample[<span style="color:#e6db74">&#34;wav&#34;</span>]))
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> {<span style="color:#e6db74">&#34;image&#34;</span>: img, <span style="color:#e6db74">&#34;caption&#34;</span>: txt, <span style="color:#e6db74">&#34;audio&#34;</span>: wav}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>ds <span style="color:#f92672">=</span> (wds<span style="color:#f92672">.</span>WebDataset(<span style="color:#e6db74">&#34;s3://my-bucket/train-{00000..00999}.tar.zst&#34;</span>)
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">.</span>decode(<span style="color:#e6db74">&#34;torchrgb&#34;</span>)
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">.</span>map(decode)
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">.</span>batched(<span style="color:#ae81ff">64</span>)
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">.</span>prefetch(<span style="color:#ae81ff">2</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>loader <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>utils<span style="color:#f92672">.</span>data<span style="color:#f92672">.</span>DataLoader(ds, num_workers<span style="color:#f92672">=</span><span style="color:#ae81ff">8</span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> batch <span style="color:#f92672">in</span> loader:
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># feed to model …</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">pass</span>
</span></span></code></pre></div></li>
</ol>
<hr>
<h2 id="新兴趋势与面向未来的准备">新兴趋势与面向未来的准备</h2>
<table>
<thead>
<tr>
<th>趋势</th>
<th>为什么现在重要</th>
<th>快速行动</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>统一多模态容器</strong>（Meta 的 MDS、DeepLake）</td>
<td>单一文件类型即可容纳文本、图像、视频、音频和嵌入，并内置版本管理。</td>
<td>试点 DeepLake；它可与 LangChain 和 LlamaIndex 集成。</td>
</tr>
<tr>
<td><strong>零拷贝 GPU‑direct 存储</strong></td>
<td>NVMe‑over‑Fabric + GPUDirect 让压缩分片直接流入 GPU 内存。</td>
<td>若拥有 NVMe‑SSD 池，启用 <code>torch.utils.data.DataLoader(persistent_workers=True)</code>。</td>
</tr>
<tr>
<td><strong>模式演进友好格式</strong></td>
<td>Arrow 13+ 支持在不重新写入整个数据集的情况下增删字段。</td>
<td>对可能后续加入深度图、视频或额外元数据的流水线，优先使用 Arrow/Parquet。</td>
</tr>
<tr>
<td><strong>自监督预编码</strong></td>
<td>存储 CLIP 图像嵌入或 wav2vec 音频嵌入，可将微调计算降低 2‑3×。</td>
<td>在 Arrow 表中新增 <code>image_emb</code>（float16）列；保留原始图像以备后续实验。</td>
</tr>
<tr>
<td><strong>隐私保护存储</strong></td>
<td>加密 TFRecord + 安全 enclave 正在为 GDPR 重负载领域提供方案。</td>
<td>若处理 PII，评估使用自定义加密包装器的 <code>tf.io.TFRecordWriter</code>。</td>
</tr>
<tr>
<td><strong>数据中心 AI 指标</strong></td>
<td>数据质量分数（OCR 置信度、模糊度、信噪比）已成为一等超参数。</td>
<td>将每个分片的质量分数写入清单，并在训练时过滤低质量分片。</td>
</tr>
</tbody>
</table>
<hr>
<h2 id="生产就绪检查清单">生产就绪检查清单</h2>
<ul>
<li><strong><input disabled="" type="checkbox"> </strong> 将模式文件（<code>.proto</code> 或 Arrow 模式）与数据一起保存。</li>
<li><strong><input disabled="" type="checkbox"> </strong> 所有分片使用快速编解码器压缩（推荐 ZSTD‑L3）。</li>
<li><strong><input disabled="" type="checkbox"> </strong> 分片大小控制在 256 MiB 到 1 GiB 之间。</li>
<li><strong><input disabled="" type="checkbox"> </strong> 清单包含校验和、记录数、每个分片统计以及预处理代码的 git hash。</li>
<li><strong><input disabled="" type="checkbox"> </strong> 使用不可变版本控制（DVC、LakeFS 或类似工具）。</li>
<li><strong><input disabled="" type="checkbox"> </strong> 为每个分片记录数据质量指标。</li>
<li><strong><input disabled="" type="checkbox"> </strong> 完成隐私审计（PII 剔除，可选加密）。</li>
<li><strong><input disabled="" type="checkbox"> </strong> 端到端测试加载器能够无错误读取随机分片。</li>
<li><strong><input disabled="" type="checkbox"> </strong> 编写 README，说明模式、预处理步骤以及如何重新生成分片。</li>
</ul>
<p>遵循此蓝图，您的训练流水线将保持 <strong>快速、低成本且可复现</strong>——现代 LLM 团队必须具备的三大支柱。</p>
<hr>
<p><em>Tags:</em> <code>data‑engineering</code> <code>multi‑modal‑llm</code> <code>training‑pipelines</code><br>
<em>Slug:</em> <code>how-to-prepare-data-file-formats-for-ai-training</code></p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
