MoE架构下的Qwen3-Coder-30B-A3B-Instruct到底有多快

Qwen3-Coder-30B-A3B-Instruct 又叫Qwen3-Coder-Flash,它具有以下特性:

  • 类型:因果语言模型
  • 训练阶段:预训练 & 后训练
  • 参数数量:总共 30.5B,激活 3.3B
  • 层数:48
  • 注意力头数(GQA):Q 为 32,KV 为 4
  • 专家数量:128
  • 激活的专家数量:8
  • 上下文长度:原生 262,144

为了验证MoE架构相比传统架构到底能有多快,这里做一个不太一致的对比:用更小尺寸的Qwen2.5-Coder-14B来进行比较。它的参数如下:

  • 类型:因果语言模型
  • 训练阶段:预训练
  • 架构:带有 RoPE、SwiGLU、RMSNorm 和 Attention QKV 偏置的 transformers
  • 参数数量:14.7B
  • 非嵌入参数数量:13.1B
  • 层数:48
  • 注意力头数(GQA):Q 为 40,KV 为 8

运行环境为M2 Max,LM-Studio, 模型实际尺寸对比:

提示词:

用C语言实现一个AAC_ADTS解析函数并提供测试用例

先使用默认参数加载2.5-14B版本

好的,下面是一个用C语言实现的AAC_ADTS(Advanced Audio Coding - Advanced Digital Audio Transport Stream)解析函数,以及一个简单的测试用例。

### AAC_ADTS 解析函数

```c
#include <stdio.h>
#include <stdint.h>

typedef struct {
    uint8_t syncword;          // 同步字,固定为 0xFFE
    uint8_t id;                // MPEG Version, 0 for MPEG-4, 1 for MPEG-2
    uint8_t layer;             // 预留,固定为 0
    uint8_t protection_absent; // 是否没有 CRC 校验
    uint8_t profile;           // 音频对象类型
    uint8_t sample_rate_index; // 采样率索引
    uint8_t private_bit;       // 私有位
    uint8_t channel_configuration; // 声道配置
    uint8_t original_copy;     // 原始/副本标志
    uint8_t home;              // 主码流标志
    uint16_t aac_frame_length;  // AAC 帧长度,包括 ADTS 头
    uint16_t adts_buffer_fullness; // ADTS 缓冲区满度
    uint8_t no_raw_data_blocks_in_frame; // 帧中原始数据块的数量
} AAC_ADTS;

int parse_aac_adts(uint8_t *data, AAC_ADTS *adts) {
    if (data == NULL || adts == NULL) {
        return -1;
    }

    // 同步字
    adts->syncword = (data[0] << 8) | data[1];
    if (adts->syncword != 0xFFE) {
        return -2;
    }

    // 解析其他字段
    adts->id = (data[1] & 0x8) >> 3;
    adts->layer = (data[1] & 0x6) >> 1;
    adts->protection_absent = (data[1] & 0x1);
    adts->profile = (data[2] & 0xF8) >> 3;
    adts->sample_rate_index = (data[2] & 0x7) << 1 | ((data[3] & 0x8) >> 3);
    adts->private_bit = (data[3] & 0x4) >> 2;
    adts->channel_configuration = (data[3] & 0x7) << 2 | ((data[4] & 0xC0) >> 6);
    adts->original_copy = (data[4] & 0x2) >> 1;
    adts->home = (data[4] & 0x1);
    adts->aac_frame_length = ((data[3] & 0x3) << 11) | (data[4] << 3) | ((data[5] & 0xE0) >> 5);
    adts->adts_buffer_fullness = ((data[5] & 0x1F) << 6) | ((data[6] & 0xFC) >> 2);
    adts->no_raw_data_blocks_in_frame = (data[6] & 0x3) + 1;

    return 0;
}

void print_adts_info(AAC_ADTS *adts) {
    if (adts == NULL) {
        return;
    }

    printf("Syncword: 0x%X\n", adts->syncword);
    printf("MPEG Version: %s\n", adts->id ? "MPEG-2" : "MPEG-4");
    printf("Layer: %d\n", adts->layer);
    printf("Protection Absent: %s\n", adts->protection_absent ? "Yes" : "No");
    printf("Profile: %d\n", adts->profile);
    printf("Sample Rate Index: %d\n", adts->sample_rate_index);
    printf("Private Bit: %s\n", adts->private_bit ? "Yes" : "No");
    printf("Channel Configuration: %d\n", adts->channel_configuration);
    printf("Original/Copy: %s\n", adts->original_copy ? "Original" : "Copy");
    printf("Home: %s\n", adts->home ? "Yes" : "No");
    printf("AAC Frame Length: %d\n", adts->aac_frame_length);
    printf("ADTS Buffer Fullness: 0x%X\n", adts->adts_buffer_fullness);
    printf("No Raw Data Blocks in Frame: %d\n", adts->no_raw_data_blocks_in_frame);
}
```

### 测试用例

```c
#include <stdio.h>

int main() {
    uint8_t adts_data[] = {
        0xFF, 0xF1, // 同步字
        0x90,       // 高8位,ID=1 (MPEG-2), Layer=3, Protection Absent=0
        0x89        // 高4位,Profile=1 (AAC LC), 低3位,Sample Rate Index=9 (48kHz)
                    // 低4位,Private Bit=0, Channel Configuration=1 (单声道)
    };

    AAC_ADTS adts;

    if (parse_aac_adts(adts_data, &adts) == 0) {
        print_adts_info(&adts);
    } else {
        printf("Parse AAC_ADTS failed.\n");
    }

    return 0;
}
```

### 解释

1. **AAC_ADTS 结构体**:定义了 ADTS 头的各个字段。
2. **parse_aac_adts 函数**:解析输入的数据,填充 AAC_ADTS 结构体。
3. **print_adts_info 函数**:打印 ADTS 头的信息。
4. **测试用例**:包含一个简单的 AAC_ADTS 数据和解析函数的测试。

编译并运行这个程序,你将看到 ADTS 头的各项信息被正确解析和打印出来。
"stats": {
    "stopReason": "eosFound",
    "tokensPerSecond": 37.553164424305415,
    "numGpuLayers": -1,
    "timeToFirstTokenSec": 0.418,
    "promptTokensCount": 44,
    "predictedTokensCount": 1346,
    "totalTokensCount": 1390
  }

Qwen2.5-Coder-14B 生成了总计1390个token,37.55 token/s

接下来卸载后加载Qwen3-Coder-30B-A3B

我将为您实现一个AAC_ADTS解析函数,包括完整的解析逻辑和测试用例。

```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

// AAC ADTS头结构定义
typedef struct {
    uint8_t syncword[12];           // 同步字,固定值0xFFF
    uint8_t id;                     // MPEG版本,0为MPEG-4,1为MPEG-2
    uint8_t layer;                  // 层,固定为0
    uint8_t protection_absent;      // 是否有CRC校验
    uint8_t profile;                // 配置文件,0为AAC LC,1为AAC LTP等
    uint8_t sampling_frequency_index; // 采样率索引
    uint8_t private_bit;            // 私有位,固定为0
    uint8_t channel_configuration;  // 声道配置
    uint8_t original;               // 是否为原始流
    uint8_t home;                   // 家庭标志,固定为0
    uint8_t copyright_identification_bit; // 版权标识位
    uint8_t copyright_identification_start; // 版权标识起始位
    uint16_t aac_frame_length;      // AAC帧长度
    uint8_t adts_buffer_fullness;   // 缓冲区满度
    uint8_t number_of_raw_data_blocks_in_frame; // 帧中原始数据块数量
} aac_adts_header_t;

// 采样率映射表
static const uint32_t sampling_rates[] = {
    96000, 88200, 64000, 48000, 44100, 32000,
    24000, 22050, 16000, 12000, 11025, 8000, 7350
};

// 解析AAC ADTS头
int parse_adts_header(uint8_t* data, size_t data_len, aac_adts_header_t* header) {
    if (!data || !header || data_len < 7) {
        return -1; // 数据不足或参数错误
    }
    
    // 检查同步字是否为0xFFF
    uint16_t syncword = (data[0] << 4) | (data[1] >> 4);
    if (syncword != 0xFFF) {
        return -2; // 同步字错误
    }
    
    // 解析ADTS头字段
    header->id = (data[1] >> 3) & 0x01;
    header->layer = (data[1] >> 1) & 0x03;
    header->protection_absent = data[1] & 0x01;
    
    header->profile = (data[2] >> 6) & 0x03;
    header->sampling_frequency_index = (data[2] >> 2) & 0x0F;
    header->private_bit = (data[2] >> 1) & 0x01;
    
    header->channel_configuration = ((data[2] & 0x01) << 2) | ((data[3] >> 6) & 0x03);
    header->original = (data[3] >> 5) & 0x01;
    header->home = (data[3] >> 4) & 0x01;
    header->copyright_identification_bit = (data[3] >> 3) & 0x01;
    header->copyright_identification_start = (data[3] >> 2) & 0x01;
    
    header->aac_frame_length = ((data[3] & 0x03) << 11) | (data[4] << 3) | (data[5] >> 5);
    
    header->adts_buffer_fullness = ((data[5] & 0x1F) << 5) | (data[6] >> 3);
    header->number_of_raw_data_blocks_in_frame = data[6] & 0x03;
    
    // 验证采样率索引
    if (header->sampling_frequency_index >= 13) {
        return -3; // 采样率索引无效
    }
    
    return 0; // 解析成功
}

// 获取采样率
uint32_t get_sampling_rate(const aac_adts_header_t* header) {
    if (!header || header->sampling_frequency_index >= 13) {
        return 0;
    }
    return sampling_rates[header->sampling_frequency_index];
}

// 获取声道数
uint8_t get_channel_count(const aac_adts_header_t* header) {
    if (!header) {
        return 0;
    }
    
    // 根据通道配置计算声道数
    static const uint8_t channel_counts[] = {0, 1, 2, 3, 4, 5, 6, 8};
    if (header->channel_configuration < 8) {
        return channel_counts[header->channel_configuration];
    }
    
    return header->channel_configuration;
}

// 打印ADTS头信息
void print_adts_header(const aac_adts_header_t* header) {
    if (!header) {
        printf("Invalid header pointer\n");
        return;
    }
    
    printf("=== AAC ADTS Header Information ===\n");
    printf("Syncword: 0x%04X\n", (header->syncword[0] << 4) | (header->syncword[1] >> 4));
    printf("MPEG Version: %s\n", header->id ? "MPEG-2" : "MPEG-4");
    printf("Profile: %d (0=AAC LC, 1=AAC LTP)\n", header->profile);
    printf("Sampling Rate: %u Hz\n", get_sampling_rate(header));
    printf("Channels: %d\n", get_channel_count(header));
    printf("Frame Length: %d bytes\n", header->aac_frame_length);
    printf("Buffer Fullness: %d\n", header->adts_buffer_fullness);
    printf("Raw Data Blocks: %d\n", header->number_of_raw_data_blocks_in_frame);
    printf("Protection: %s\n", header->protection_absent ? "None" : "With CRC");
    printf("==================================\n");
}

// 创建测试用例数据(模拟ADTS帧)
uint8_t* create_test_adts_frame(size_t* frame_size) {
    // 创建一个简单的ADTS帧(模拟数据)
    static uint8_t test_frame[] = {
        0xFF, 0xF1, 0x50, 0x00, 0x00, 0x00, 0x00, // ADTS头
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    
    *frame_size = sizeof(test_frame);
    return test_frame;
}

// 创建有效的ADTS帧数据
uint8_t* create_valid_adts_frame(size_t* frame_size) {
    static uint8_t valid_frame[1024];
    
    // 填充ADTS头(简化版本)
    valid_frame[0] = 0xFF; // syncword[12:8]
    valid_frame[1] = 0xF1; // syncword[7:0] + id + layer + protection_absent
    valid_frame[2] = 0x50; // profile + sampling_frequency_index + private_bit
    valid_frame[3] = 0x00; // channel_configuration + original + home
    valid_frame[4] = 0x00; // copyright_identification_bit + copyright_identification_start + aac_frame_length[15:8]
    valid_frame[5] = 0x00; // aac_frame_length[7:0]
    valid_frame[6] = 0x00; // adts_buffer_fullness + number_of_raw_data_blocks_in_frame
    
    *frame_size = 7; // 基本头长度
    return valid_frame;
}

// 测试函数
void run_tests() {
    printf("=== AAC ADTS Parser Test Suite ===\n\n");
    
    // 测试1: 有效ADTS头解析
    printf("Test 1: Valid ADTS Header Parsing\n");
    {
        uint8_t test_data[] = {
            0xFF, 0xF1, 0x50, 0x00, 0x00, 0x00, 0x00
        };
        
        aac_adts_header_t header;
        int result = parse_adts_header(test_data, sizeof(test_data), &header);
        
        printf("Parse result: %d (0=success, -1=param error, -2=sync error, -3=rate error)\n", result);
        if (result == 0) {
            print_adts_header(&header);
        }
        printf("\n");
    }
    
    // 测试2: 无效同步字
    printf("Test 2: Invalid Syncword\n");
    {
        uint8_t invalid_data[] = {
            0xFF, 0xF0, 0x50, 0x00, 0x00, 0x00, 0x00
        };
        
        aac_adts_header_t header;
        int result = parse_adts_header(invalid_data, sizeof(invalid_data), &header);
        
        printf("Parse result: %d\n", result);
        printf("Expected: -2 (syncword error)\n\n");
    }
    
    // 测试3: 空指针测试
    printf("Test 3: Null Pointer Test\n");
    {
        int result = parse_adts_header(NULL, 10, NULL);
        printf("Parse result with null pointers: %d\n", result);
        printf("Expected: -1 (parameter error)\n\n");
    }
    
    // 测试4: 数据不足测试
    printf("Test 4: Insufficient Data\n");
    {
        uint8_t short_data[] = {0xFF, 0xF1};
        aac_adts_header_t header;
        int result = parse_adts_header(short_data, 2, &header);
        
        printf("Parse result with short data: %d\n", result);
        printf("Expected: -1 (insufficient data)\n\n");
    }
    
    // 测试5: 采样率解析测试
    printf("Test 5: Sampling Rate Resolution\n");
    {
        uint8_t test_data[] = {
            0xFF, 0xF1, 0x54, 0x00, 0x00, 0x00, 0x00
        };
        
        aac_adts_header_t header;
        int result = parse_adts_header(test_data, sizeof(test_data), &header);
        
        if (result == 0) {
            printf("Sampling rate: %u Hz\n", get_sampling_rate(&header));
            printf("Expected for index 4: 44100 Hz\n");
        }
        printf("\n");
    }
    
    // 测试6: 声道数解析测试
    printf("Test 6: Channel Count Resolution\n");
    {
        uint8_t test_data[] = {
            0xFF, 0xF1, 0x50, 0x02, 0x00, 0x00, 0x00
        };
        
        aac_adts_header_t header;
        int result = parse_adts_header(test_data, sizeof(test_data), &header);
        
        if (result == 0) {
            printf("Channel count: %d\n", get_channel_count(&header));
            printf("Expected for config 2: 2 channels\n");
        }
        printf("\n");
    }
    
    // 测试7: 详细信息显示测试
    printf("Test 7: Detailed Information Display\n");
    {
        uint8_t test_data[] = {
            0xFF, 0xF1, 0x54, 0x02, 0x00, 0x00, 0x00
        };
        
        aac_adts_header_t header;
        int result = parse_adts_header(test_data, sizeof(test_data), &header);
        
        if (result == 0) {
            print_adts_header(&header);
        }
        printf("\n");
    }
    
    // 测试8: 多种采样率测试
    printf("Test 8: Different Sampling Rates\n");
    {
        uint8_t test_rates[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
        
        for (int i = 0; i < 13; i++) {
            uint8_t test_data[7] = {0xFF, 0xF1, 0x50, 0x00, 0x00, 0x00, 0x00};
            test_data[2] = (test_data[2] & 0xF0) | (i & 0x0F); // 设置采样率索引
            
            aac_adts_header_t header;
            int result = parse_adts_header(test_data, 7, &header);
            
            if (result == 0) {
                printf("Rate index %d: %u Hz\n", i, get_sampling_rate(&header));
            }
        }
        printf("\n");
    }
}

// 性能测试函数
void performance_test() {
    printf("=== Performance Test ===\n");
    
    // 创建大量测试数据
    uint8_t* test_data = (uint8_t*)malloc(1000000);
    if (!test_data) {
        printf("Memory allocation failed\n");
        return;
    }
    
    // 填充测试数据
    for (size_t i = 0; i < 1000000; i += 7) {
        test_data[i] = 0xFF;
        test_data[i+1] = 0xF1;
        test_data[i+2] = 0x50;
        test_data[i+3] = 0x00;
        test_data[i+4] = 0x00;
        test_data[i+5] = 0x00;
        test_data[i+6] = 0x00;
    }
    
    // 性能测试
    clock_t start = clock();
    aac_adts_header_t header;
    
    for (int i = 0; i < 100000; i++) {
        parse_adts_header(test_data + (i * 7), 7, &header);
    }
    
    clock_t end = clock();
    double time_taken = ((double)(end - start)) / CLOCKS_PER_SEC;
    
    printf("Processed 100,000 frames in %.6f seconds\n", time_taken);
    printf("Average time per frame: %.6f microseconds\n", (time_taken * 1000000) / 100000);
    
    free(test_data);
}

// 主函数
int main() {
    printf("AAC ADTS Parser Implementation\n");
    printf("================================\n\n");
    
    // 运行测试用例
    run_tests();
    
    // 性能测试(可选)
    char choice;
    printf("Run performance test? (y/n): ");
    scanf(" %c", &choice);
    
    if (choice == 'y' || choice == 'Y') {
        performance_test();
    }
    
    printf("\n=== Test Suite Completed ===\n");
    
    return 0;
}
```

这个实现包含以下主要特性:

## 功能特点:

1. **完整的ADTS头解析**
   - 解析所有ADTS头字段
   - 验证同步字
   - 错误处理机制

2. **采样率映射**
   - 支持13种标准采样率
   - 自动转换采样率索引

3. **声道数计算**
   - 根据通道配置计算声道数
   - 支持标准配置

4. **完整的测试套件**
   - 有效解析测试
   - 错误情况测试
   - 边界条件测试
   - 性能测试

## 编译和运行:

```bash
gcc -o aac_adts_parser aac_adts_parser.c -Wall -Wextra
./aac_adts_parser
```

## 主要测试用例:

1. **正常解析**:验证有效的ADTS头解析
2. **同步字错误**:测试无效同步字检测
3. **参数验证**:空指针和数据不足测试
4. **采样率解析**:不同采样率索引测试
5. **声道计算**:通道配置解析测试
6. **性能测试**:大量数据处理性能验证

这个实现提供了完整的AAC ADTS解析功能,包括错误处理、详细的信息显示和全面的测试用例。
"stats": {
    "stopReason": "eosFound",
    "tokensPerSecond": 62.83930796482279,
    "numGpuLayers": -1,
    "timeToFirstTokenSec": 2.489,
    "promptTokensCount": 23,
    "predictedTokensCount": 3909,
    "totalTokensCount": 3932
  }

Qwen3-Coder-30B-A3B 生成了总计3932个token,62.83 token/s

总生成数 tokens生成速度 t/s
Qwen2.5-Coder-14B139037.55
Qwen3-Coder-30B-A3B393262.83

确实是,快如闪电

原创文章,转载请注明: 转载自诺德美地科技

本文链接地址: MoE架构下的Qwen3-Coder-30B-A3B-Instruct到底有多快

文章的脚注信息由WordPress的wp-posturl插件自动生成

发表评论