Files
markbaseengine/LAYER_WEIGHT_PRELOAD_PROGRESS.md
T
MarkBase Admin ac75faa0cc
CI / build-and-test (push) Has been cancelled
Initial commit: E4B-MarkBase model integration with passing tests
- E4B-MarkBase model (42 layers, 4.4GB) loaded successfully
- All Phase 1-6 tests passed (model loading, forward pass, vision/audio towers, token generation, performance)
- All stress tests passed (5/5 in 127.6s)
  - Concurrent inference
  - Memory stress (67.5 tok/s, 0 NaN)
  - Continuous generation
  - Batch processing
  - Long-running stability
- Swift Metal inference engine with multimodal support
2026-06-23 18:12:35 +08:00

3.4 KiB
Raw Blame History

Layer权重预读取优化进度

✓ 已完成

  1. 并行权重预读取实现 ✓✓✓

    • 收集所有layer权重名称 (lines 425-463)
    • 使用DispatchGroup并行读取 (lines 465-497)
    • 线程安全数组存储 (避免字典竞争)
    • 错误检查和性能计时 (lines 499-510)
  2. 编译成功 ✓✓✓

    • 修复optional unwrap问题
    • 修复guard逻辑问题
    • 构建通过 (1.60s)

🚧 待完成

  1. 修改layer construction循环

    • 当前: 循环中直接读取权重 (norm(), qw() 等)
    • 目标: 从预读取的loadedWeights数组获取数据
    • 需要修改:
      • loadNorm() → 从预读取数据创建MTLBuffer
      • quantizedGroup() → 从预读取数据创建QuantizedWeights
      • MoE权重加载 → 从预读取数据获取
  2. 性能测试

    • 当前: 未优化 (每层~1秒, 总63秒)
    • 目标: 预读取10秒, layer构建10秒, 总~20秒 (3x speedup)

📊 性能分析

  • 权重数量: ~20个/layer × 60 layers = ~1200个权重 (31B模型)
  • 预读取开销: 单次并行读取 (~10秒)
  • 当前开销: 顺序读取 (~63秒)
  • 预期提升: 63s → 20s (3x speedup)

🔧 实现细节

// 预读取数据存储 (线程安全数组)
var loadedWeights: [Data?] = Array(repeating: nil, count: allWeightNames.count)
var loadErrors: [Error?] = Array(repeating: nil, count: allWeightNames.count)

// 并行读取
for (weightIndex, name) in allWeightNames.enumerated() {
    dispatchGroup.enter()
    loadQueue.async {
        guard let desc = allTensors.first(where: { $0.name == name }) else {
            loadErrors[weightIndex] = WeightError.tensorNotFound(name)
            return
        }
        let reader = getReader(for: name)
        let data = try reader.read(tensor: desc)
        loadedWeights[weightIndex] = data
    }
    dispatchGroup.leave()
}
dispatchGroup.wait()

📝 下一步行动

  1. 修改layer construction循环

    // 原代码:
    let qp = try qw("self_attn.q_proj")  // 每次调用都读取文件
    
    // 新代码:
    let qp = try createQuantizedWeightsFromPreloaded(
        prefix: prefix, 
        name: "self_attn.q_proj",
        preloadedData: loadedWeights
    )
    
  2. 创建辅助方法

    • createNormFromPreloaded() - 从预读取数据创建norm buffer
    • createQuantizedWeightsFromPreloaded() - 从预读取数据创建量化权重
    • createMoEWeightsFromPreloaded() - 从预读取数据创建MoE权重
  3. 测试验证

    • 31B模型加载时间测试
    • MoE模型加载时间测试
    • 所有6个模型回归测试

⏱️ 预计完成时间

  • 修改layer construction循环: 30-60分钟
  • 测试验证: 15-30分钟
  • 总计: ~1-1.5小时

💡 优化思路

  • 核心瓶颈: Layer construction中的顺序文件读取
  • 解决方案: 预先并行读取所有权重,然后顺序构建layers
  • 权衡: 内存占用增加 (~权重数据在内存中), 但加载速度提升3x

🎯 ROI分析

  • 时间投入: ~1.5小时
  • 性能提升: 3x (63s → 20s)
  • 用户体验: 显著改善 (模型加载更快)
  • 优先级: 高 (主要瓶颈, 高ROI)

📂 相关文件

  • /Users/accusys/MarkBaseEngine/Sources/MarkBase/Model.swift: 预读取实现 (lines 419-510)
  • /Users/accusys/MarkBaseEngine/LAYER_LOADING_ANALYSIS.md: 瓶颈分析
  • /Users/accusys/MarkBaseEngine/OPTIMIZATION_ACHIEVEMENT.md: 优化总结