File size: 3,817 Bytes
29658b2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
export async function loadAllData() {
  try {
    const response = await fetch('./raw_data/data.json');
    const jsonData = await response.json();
    return jsonData;
  } catch (error) {
    console.error('Error loading JSON data:', error);
    return {};
  }
}

export function calculateSpeedup(specValue, baselineValue) {
  if (!specValue || !baselineValue || baselineValue === 0) return null;
  return (specValue / baselineValue).toFixed(2);
}

export function processModelData(modelData, targetModelName) {
  if (!modelData || !targetModelName) return [];

  // Map to hold aggregated entries by unique key (draftModel + config)
  const entriesMap = new Map();

  // Iterate through each benchmark in the model
  Object.entries(modelData).forEach(([, benchmarkData]) => {
    const benchmarkName = benchmarkData.benchmark_name;
    const results = benchmarkData.results || [];

    results.forEach(result => {
      const { batch_size, steps, topk, num_draft_tokens, metrics } = result;

      // Find baseline (Without EAGLE3)
      const baselineMetric = metrics.find(m => m.Name === 'Wihtout EAGLE3');

      // Process each metric entry (including baseline and EAGLE3 models)
      metrics.forEach(metric => {
        const isBaseline = metric.Name === 'Wihtout EAGLE3';
        const config = isBaseline ? 'baseline' : `${batch_size}-${steps}-${topk}-${num_draft_tokens}`;

        // draftModel is the Name from metrics array
        const draftModel = isBaseline ? 'None' : metric.Name;

        // Use a combination of draftModel and config as the key
        // This ensures baseline and EAGLE3 configs are separate entries
        const key = `${draftModel}|${config}`;

        // Get or create entry
        if (!entriesMap.has(key)) {
          entriesMap.set(key, {
            targetModel: targetModelName,
            draftModel: draftModel,
            config,
            batch_size,
            steps,
            topk,
            num_draft_tokens,
            metrics: {},
            baseline: {}
          });
        }

        const entry = entriesMap.get(key);

        // Add this benchmark's metrics
        entry.metrics[benchmarkName] = {
          throughput: metric.output_throughput,
          accLen: metric.accept_length
        };

        // Add baseline for this benchmark
        if (baselineMetric) {
          entry.baseline[benchmarkName] = {
            throughput: baselineMetric.output_throughput,
            accLen: baselineMetric.accept_length
          };
        }
      });
    });
  });

  return Array.from(entriesMap.values());
}

export function getTargetModels(allData) {
  return Object.keys(allData);
}

export function extractUniqueTargetModels(processedData) {
  return [...new Set(processedData.map(d => d.targetModel).filter(Boolean))];
}

export function removeSGLangPrefix(modelName) {
  if (!modelName) return modelName;
  // Remove "SGLang-EAGLE3" prefix if present (handles various formats)
  // Examples: "lmsys/SGLang-EAGLE3-..." -> "lmsys/..."
  //           "SGLang-EAGLE3/..." -> "..."
  //           "SGLang-EAGLE3-..." -> "..."
  let cleaned = String(modelName);

  // Remove "SGLang-EAGLE3-" pattern (with hyphen after, can be preceded by / or start of string)
  cleaned = cleaned.replace(/(^|\/)SGLang-EAGLE3-/gi, '$1');

  // Remove "SGLang-EAGLE3/" pattern (with slash after)
  cleaned = cleaned.replace(/(^|\/)SGLang-EAGLE3\//gi, '$1');

  // Remove standalone "SGLang-EAGLE3" at the start (not followed by - or /)
  cleaned = cleaned.replace(/^SGLang-EAGLE3(?![-\/])/gi, '');

  // Clean up any double slashes
  cleaned = cleaned.replace(/\/+/g, '/');

  // Remove leading slash if present (unless it's the only character)
  if (cleaned.length > 1) {
    cleaned = cleaned.replace(/^\//, '');
  }

  return cleaned || modelName;
}