File size: 8,127 Bytes
bdc3b7b fd3c30a bdc3b7b fd3c30a bdc3b7b |
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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
"""Apple Silicon 芯片信息获取工具"""
import json
import subprocess
import platform
from typing import Dict, Optional
from dataclasses import dataclass
__all__ = ('AppleSiliconInfo', 'get_apple_silicon_info')
@dataclass
class AppleSiliconInfo:
"""Apple Silicon 芯片信息"""
chip_name: str # 如 "Apple M1", "Apple M1 Pro", "Apple M2 Max"
total_cores: int # 总核心数
performance_cores: int # 性能核心数(P-cores)
efficiency_cores: int # 效率核心数(E-cores)
gpu_cores: int # GPU核心数
memory_gb: int # 内存大小(GB)
is_apple_silicon: bool # 是否为Apple Silicon
def _get_system_profiler_info() -> Optional[Dict]:
"""通过system_profiler获取硬件信息"""
try:
# 获取硬件信息
result = subprocess.run([
'system_profiler', 'SPHardwareDataType', '-json'
], capture_output=True, text=True, timeout=10)
if result.returncode == 0:
data = json.loads(result.stdout)
return data.get('SPHardwareDataType', [{}])[0]
except (subprocess.TimeoutExpired, json.JSONDecodeError, FileNotFoundError):
pass
return None
def _parse_cpu_info_from_sysctl() -> Optional[Dict]:
"""通过sysctl获取CPU信息"""
try:
# 获取CPU核心信息
result = subprocess.run([
'sysctl', '-n',
'hw.perflevel0.physicalcpu', # 性能核心数
'hw.perflevel1.physicalcpu', # 效率核心数
'hw.logicalcpu', # 逻辑核心数
'hw.memsize' # 内存大小
], capture_output=True, text=True, timeout=5)
if result.returncode == 0:
lines = result.stdout.strip().split('\n')
if len(lines) >= 4:
return {
'performance_cores': int(lines[0]) if lines[0].isdigit() else 0,
'efficiency_cores': int(lines[1]) if lines[1].isdigit() else 0,
'total_cores': int(lines[2]) if lines[2].isdigit() else 0,
'memory_bytes': int(lines[3]) if lines[3].isdigit() else 0
}
except (subprocess.TimeoutExpired, ValueError, IndexError, FileNotFoundError):
pass
return None
def _get_gpu_cores_from_system_profiler() -> int:
"""获取GPU核心数"""
try:
result = subprocess.run([
'system_profiler', 'SPDisplaysDataType', '-json'
], capture_output=True, text=True, timeout=10)
if result.returncode == 0:
data = json.loads(result.stdout)
displays = data.get('SPDisplaysDataType', [])
for display in displays:
if 'sppci_cores' in display:
return int(display['sppci_cores'])
# 根据芯片名称估算GPU核心数
model = display.get('sppci_model', '').lower()
if 'm1 max' in model:
return 32
elif 'm1 pro' in model:
return 16 if '16-core' in model else 14
elif 'm1' in model:
return 8 if '8-core' in model else 7
elif 'm2 max' in model:
return 38
elif 'm2 pro' in model:
return 19 if '19-core' in model else 16
elif 'm2' in model:
return 10 if '10-core' in model else 8
elif 'm3 max' in model:
return 40
elif 'm3 pro' in model:
return 18 if '18-core' in model else 14
elif 'm3' in model:
return 10 if '10-core' in model else 8
except (subprocess.TimeoutExpired, json.JSONDecodeError, ValueError, FileNotFoundError):
pass
return 8 # 默认值
def get_apple_silicon_info() -> AppleSiliconInfo:
"""
获取Apple Silicon芯片信息
Returns:
AppleSiliconInfo: 芯片信息对象
"""
# 检查是否为Apple Silicon
machine = platform.machine()
is_apple_silicon = machine in ('arm64', 'arm64e') and platform.system() == 'Darwin'
if not is_apple_silicon:
return AppleSiliconInfo(
chip_name="非Apple Silicon",
total_cores=1,
performance_cores=1,
efficiency_cores=0,
gpu_cores=0,
memory_gb=8,
is_apple_silicon=False
)
# 获取系统信息
hw_info = _get_system_profiler_info()
cpu_info = _parse_cpu_info_from_sysctl()
# 解析芯片名称
chip_name = "Apple Silicon"
if hw_info and 'chip_type' in hw_info:
chip_name = hw_info['chip_type']
elif hw_info and 'cpu_type' in hw_info:
chip_name = hw_info['cpu_type']
# 解析核心信息
performance_cores = 4 # 默认值
efficiency_cores = 4 # 默认值
total_cores = 8 # 默认值
if cpu_info:
performance_cores = cpu_info.get('performance_cores', performance_cores)
efficiency_cores = cpu_info.get('efficiency_cores', efficiency_cores)
total_cores = cpu_info.get('total_cores', total_cores)
# 如果sysctl失败,尝试从芯片名称推断
if performance_cores == 0 and efficiency_cores == 0:
chip_lower = chip_name.lower()
if 'm1 max' in chip_lower:
performance_cores, efficiency_cores = 8, 2
elif 'm1 pro' in chip_lower:
performance_cores, efficiency_cores = 8, 2
elif 'm1' in chip_lower:
performance_cores, efficiency_cores = 4, 4
elif 'm2 max' in chip_lower:
performance_cores, efficiency_cores = 8, 4
elif 'm2 pro' in chip_lower:
performance_cores, efficiency_cores = 8, 4
elif 'm2' in chip_lower:
performance_cores, efficiency_cores = 4, 4
elif 'm3' in chip_lower:
if 'max' in chip_lower:
performance_cores, efficiency_cores = 12, 4
elif 'pro' in chip_lower:
performance_cores, efficiency_cores = 8, 4
else:
performance_cores, efficiency_cores = 4, 4
total_cores = performance_cores + efficiency_cores
# 获取内存大小
memory_gb = 8 # 默认值
if cpu_info and 'memory_bytes' in cpu_info:
memory_gb = cpu_info['memory_bytes'] // (1024 ** 3)
elif hw_info and 'physical_memory' in hw_info:
memory_str = hw_info['physical_memory'].replace(' GB', '').replace(',', '')
try:
memory_gb = int(memory_str)
except ValueError:
pass
# 获取GPU核心数
gpu_cores = _get_gpu_cores_from_system_profiler()
return AppleSiliconInfo(
chip_name=chip_name,
total_cores=total_cores,
performance_cores=performance_cores,
efficiency_cores=efficiency_cores,
gpu_cores=gpu_cores,
memory_gb=memory_gb,
is_apple_silicon=True
)
def get_optimal_llama_cpp_config() -> Dict[str, int]:
"""
根据Apple Silicon芯片信息获取最优的llama.cpp配置
Returns:
Dict[str, int]: 包含n_threads和n_ctx的配置
"""
chip_info = get_apple_silicon_info()
if not chip_info.is_apple_silicon:
# 非Apple Silicon系统的默认配置
return {
'n_threads': 4,
'n_ctx': 2048
}
# 对于Apple Silicon,只使用性能核心(P-cores)
# 避免混合使用效率核心,以获得最佳性能
n_threads = chip_info.performance_cores
# 根据内存大小调整上下文窗口
if chip_info.memory_gb >= 32:
n_ctx = 4096
elif chip_info.memory_gb >= 16:
n_ctx = 2048
else:
n_ctx = 1024
return {
'n_threads': n_threads,
'n_ctx': n_ctx
}
if __name__ == '__main__':
# 测试功能
info = get_apple_silicon_info()
print(f"芯片信息: {info}")
config = get_optimal_llama_cpp_config()
print(f"推荐配置: {config}") |