import argparse
from collections import defaultdict
from pathlib import Path
import re
import pandas as pd
def extract_log_info(log_file, profile_dir='./profile', output_file='log_analysis.xlsx'):
"""
提取日志文件中各模型的训练时间信息和profile数据
Args:
log_file: 日志文件路径
profile_dir: profile数据目录路径
output_file: 输出Excel文件路径
"""
model_pattern = r'(npu|cuda)\s+train\s+(\S+)'
eager_pattern = r'eager.*avg step time:\s*([\d\.]+)\s*ms'
compile_pattern = r'compile.*avg step time:\s*([\d\.]+)\s*ms'
op_compile_time_pattern = r'op_compile_time:\s*([\d\.]+)\s*ms'
data = defaultdict(lambda: {
'accuracy': None,
'eager_E2E_avg_time': None,
'compile_E2E_avg_time': None,
'op_compile_time': None,
'eager_OP_avg_time': None,
'compile_OP_avg_time': None
})
current_model = None
in_compile_block = False
compile_block_lines = []
with open(log_file, 'r', encoding='utf-8') as f:
lines = f.readlines()
for _, line in enumerate(lines):
model_match = re.search(model_pattern, line)
if model_match:
if current_model and in_compile_block and compile_block_lines:
for log_line in compile_block_lines:
if 'pass_accuracy' in log_line:
data[current_model]['accuracy'] = log_line.strip()
break
for log_line in compile_block_lines:
op_compile_match = re.search(op_compile_time_pattern, log_line)
if op_compile_match:
data[current_model]['op_compile_time'] = float(op_compile_match.group(1))
break
current_model = model_match.group(2)
in_compile_block = False
compile_block_lines = []
continue
if current_model:
eager_match = re.search(eager_pattern, line)
if eager_match:
data[current_model]['eager_E2E_avg_time'] = float(eager_match.group(1))
compile_match = re.search(compile_pattern, line)
if compile_match:
data[current_model]['compile_E2E_avg_time'] = float(compile_match.group(1))
in_compile_block = True
compile_block_lines = []
if current_model and in_compile_block:
compile_block_lines.append(line)
if current_model and in_compile_block and compile_block_lines:
for log_line in compile_block_lines:
if 'pass_accuracy' in log_line:
data[current_model]['accuracy'] = log_line.strip()
break
for log_line in compile_block_lines:
op_compile_match = re.search(op_compile_time_pattern, log_line)
if op_compile_match:
data[current_model]['op_compile_time'] = float(op_compile_match.group(1))
break
profile_path = Path(profile_dir)
if profile_path.exists():
for model_dir in profile_path.iterdir():
if model_dir.is_dir():
model_name = model_dir.name
eager_dir = model_dir / 'eager'
if eager_dir.exists() and eager_dir.is_dir():
eager_subdirs = list(eager_dir.iterdir())
if eager_subdirs:
eager_subdir = eager_subdirs[0]
eager_csv_path = eager_subdir / 'ASCEND_PROFILER_OUTPUT' / 'step_trace_time.csv'
if eager_csv_path.exists():
try:
eager_df = pd.read_csv(eager_csv_path, sep=',')
if 'Computing' in eager_df.columns:
data[model_name]['eager_OP_avg_time'] = eager_df['Computing'].mean() / 1e3
else:
print(f"警告: {eager_csv_path} 中没有Computing列")
except Exception as e:
print(f"读取{eager_csv_path}时出错: {e}")
compile_dir = model_dir / 'compile'
if compile_dir.exists() and compile_dir.is_dir():
compile_subdirs = list(compile_dir.iterdir())
if compile_subdirs:
compile_subdir = compile_subdirs[0]
compile_csv_path = compile_subdir / 'ASCEND_PROFILER_OUTPUT' / 'step_trace_time.csv'
if compile_csv_path.exists():
try:
compile_df = pd.read_csv(compile_csv_path, sep=',')
if 'Computing' in compile_df.columns:
data[model_name]['compile_OP_avg_time'] = compile_df['Computing'].mean() / 1e3
else:
print(f"警告: {compile_csv_path} 中没有Computing列")
except Exception as e:
print(f"读取{compile_csv_path}时出错: {e}")
else:
print(f"警告: profile目录不存在: {profile_dir}")
df = pd.DataFrame.from_dict(data, orient='index')
df.index.name = 'model_name'
df.reset_index(inplace=True)
df['E2E_speed_up_rate'] = df.apply(
lambda row: row['eager_E2E_avg_time'] / row['compile_E2E_avg_time']
if row['compile_E2E_avg_time'] and row['compile_E2E_avg_time'] != 0 else None,
axis=1
)
df['OP_speed_up_rate'] = df.apply(
lambda row: row['eager_OP_avg_time'] / row['compile_OP_avg_time']
if row['compile_OP_avg_time'] and row['compile_OP_avg_time'] != 0 else None,
axis=1
)
column_order = [
'model_name', 'accuracy', 'op_compile_time',
'eager_E2E_avg_time', 'compile_E2E_avg_time', 'E2E_speed_up_rate',
'eager_OP_avg_time', 'compile_OP_avg_time', 'OP_speed_up_rate'
]
existing_columns = [col for col in column_order if col in df.columns]
df = df[existing_columns + [col for col in df.columns if col not in existing_columns]]
df.to_excel(output_file, index=False)
return df
def main():
parser = argparse.ArgumentParser(description='提取日志文件中的训练时间信息和profile数据')
parser.add_argument('--log_file', required=True, help='日志文件路径')
parser.add_argument('--profile_dir', default='./profile', help='profile数据目录路径,默认为./profile')
parser.add_argument('--output_file', default='analysis.xlsx', help='输出Excel文件路径,默认为log_analysis.xlsx')
args = parser.parse_args()
result = extract_log_info(
log_file=args.log_file,
profile_dir=args.profile_dir,
output_file=args.output_file
)
print(f"提取完成,共找到{len(result)}个模型")
print("\n提取结果:")
print(result.head())
if __name__ == "__main__":
main()