如何简化nvidia-smi输出提取正则,高效获取各GPU全部对应指标
优化nvidia-smi文本解析方案
卡顿原因说明
你原有正则出现卡顿的核心原因是嵌套的分组+非贪婪匹配触发了正则回溯爆炸,匹配失败时会尝试大量无效路径,计算开销陡增。
方案1:优化后正则表达式
使用命名捕获组直接匹配所有需要的字段,避免无效回溯:
import re gpu_pattern = re.compile( r'\|={30,}\+={20,}\+={20,}\|\n' r'\|\s*(?P<gpu_index>\d+)\s+(?P<gpu_model_name>.*?)\s+(?P<persistence_mode>\w+)\s*\|\s*(?P<bus_id>[0-9A-Fa-f:.]+)\s+(?P<display_active>\w+)\s*\|\s*(?P<volatile_ecc>.*?)\s*\|\n' r'\|\s*(?P<fan>\d+)%\s+(?P<temperature>\d+)C\s+(?P<perf>P\d+)\s+(?P<power_usage>\d+)W\s*/\s*(?P<max_power>\d+)W\s*\|\s*(?P<memory_usage>\d+)MiB\s*/\s*(?P<available_mem>\d+)MiB\s*\|\s*(?P<gpu_utilization>\d+)%\s+(?P<compute_mode>.*?)\s*\|\n' r'\|\s*.*?\|\s*.*?\|\s*(?P<multiple_instance_gpu_mode>.*?)\s*\|\n' ) # 使用方法 gpu_list = [match.groupdict() for match in gpu_pattern.finditer(your_text)]
该正则直接匹配每个GPU对应的4行块结构,明确的字段格式限定大幅降低了回溯概率,处理速度远高于原有正则。
方案2:无正则逐行解析(更稳定,适合超大文本)
完全避免正则开销,逐行拆分解析,兼容性更强:
def parse_nvidia_smi(text): lines = text.splitlines() gpu_list = [] idx = 0 # 定位到GPU块起始分隔线 while idx < len(lines): if '===============================+======================+======================' in lines[idx]: break idx += 1 # 循环解析所有GPU块 while idx < len(lines): line = lines[idx] # 跳过块结束分隔线 if '+-------------------------------+----------------------+----------------------+' in line: idx += 1 continue # 匹配到新GPU块的起始分隔线 if '===============================+======================+======================' in line: idx += 1 # 读取该GPU对应的3行数据 l1_col = [c.strip() for c in lines[idx].strip('| ').split('|')] l2_col = [c.strip() for c in lines[idx+1].strip('| ').split('|')] l3_col = [c.strip() for c in lines[idx+2].strip('| ').split('|')] idx += 3 # 解析对应列字段 l1_part1 = l1_col[0].split() l2_part1 = l2_col[0].split() l1_part2 = l1_col[1].split() l2_part2 = l2_col[1].split() l2_part3 = l2_col[2].split() gpu_list.append({ "gpu_index": int(l1_part1[0]), "gpu_model_name": " ".join(l1_part1[1:-1]), "persistence_mode": l1_part1[-1], "bus_id": l1_part2[0], "display_active": l1_part2[1], "volatile_ecc": l1_col[2], "fan": int(l2_part1[0].strip("%")), "temperature": int(l2_part1[1].strip("C")), "perf": l2_part1[2], "power_usage": int(l2_part1[3].strip("W")), "max_power": int(l2_part1[5].strip("W")), "memory_usage": int(l2_part2[0].strip("MiB")), "available_mem": int(l2_part2[2].strip("MiB")), "gpu_utilization": int(l2_part3[0].strip("%")), "compute_mode": " ".join(l2_part3[1:]), "multiple_instance_gpu_mode": l3_col[2] }) continue idx += 1 return gpu_list
该方案完全没有正则回溯风险,处理GB级文本也不会出现卡顿,且对nvidia-smi输出格式的小幅度变动兼容性更好。
内容的提问来源于stack exchange,提问作者elegantcomplexity
相关产品推荐
相关产品推荐

