技术

[数据分享] 基于 ISLP 负载实测: OCI Ampere A1 (ARM64)、Kaggle、Lightning 与本地 6800H 多线程性能对比

跑《统计学习导论》(ISLP) 实验时,顺手测了一下常用免费云端算力实例与本地标压笔记本在基础机器学习负载下的性能差异。非严格学术评测,仅记录单机工程数据供参考
一、 测试环境


  • OCI ARM:Ampere Altra 架构,4 OCPU (独立物理核),24 GB RAM ,Ubuntu 22.04
  • Lightning AI:Free CPU Studio ( 4 vCPU 共享容器)
  • Kaggle:标准 CPU 实例( 4 vCPU )及 Tesla T4 GPU 实例
  • Local:AMD Ryzen 7 6800H ( 8 核 16 线程)+ RTX 3050 Laptop (4GB VRAM)
<hr>二、 基准测试数据

1. scikit-learn:随机森林分类( CPU )


  • 数据规格:合成二分类数据集,40,000 样本,40 特征,200 棵树( 32k 训练 / 8k 测试),random_state=42。全平台测试集准确率均为 95.59%
并行任务数 (n_jobs)OCI ARM (Ampere)Lightning CPUKaggle CPURyzen 7 6800H (本地)134.12 s| 28.34 s
| 70.88 s
| 27.63 s
|| 2 | 17.74 s
| 15.54 s
| 36.97 s
| 14.12 s
|| 4 | 9.50 s
| 11.13 s
| 24.79 s
| 7.43 s
|| 8 | — | — | — | 4.50 s
|| 16 | — | — | — | 3.04 s
|
注:Kaggle CPU 在 4 线程时表现出较明显的扩展瓶颈,耗时为本地 6800H 的 3.3 倍; OCI ARM 在 1 核至 4 核间表现出接近线性的加速比(约 3.59x )
2. PyTorch:CPU 矩阵乘法( 4096×4096 ,float32 )


  • 测试逻辑:torch.set_num_interop_threads(1),显式预热,多次采样取中位数耗时
线程数 (threads)OCI ARM (Ampere)Lightning CPUKaggle CPURyzen 7 6800H (本地)13.66 s (37.5 GFLOP/s)| 0.90 s
| 2.03 s
| 1.20 s
|| 2 | 1.85 s (74.3 GFLOP/s)
| 0.48 s
| 1.05 s
| 0.64 s
|| 4 | 1.06 s (129.9 GFLOP/s)
| 0.93 s
| 1.02 s
| 0.44 s
|| 8 | — | — | — | 0.27 s
|| 16 | — | — | — | 0.24 s
|
注:Lightning CPU 在 1~2 线程下受益于 x86 高级矢量扩展(AVX)及底层优化的数学库,单核吞吐占优,但打满 4 线程时收益见顶; OCI ARM 多核扩展曲线相对平稳
3. GPU 单算子基准参照( 4096×4096 Matmul )


  • 参数设定:PyTorch float32 ,显式关闭 TF32 ,包含 torch.cuda.synchronize() 同步
硬件平台单次中位数耗时计算吞吐Ryzen 7 6800H (16 线程 CPU)236.80 ms| ~580 GFLOP/s || Kaggle Tesla T4 (16GB VRAM) | 40.86 ms
| ~3363 GFLOP/s || 本地 RTX 3050 Laptop (4GB VRAM) | 36.91 ms
| ~3723 GFLOP/s |
注:纯单算子吞吐下移动端 3050 略胜 T4 ,但 4GB 显存无法承载大规模上下文与 Batch Size ,仅适用于小模型原型快速验证
<hr>三、 观察与局限


  • 物理核 vs 容器超卖:Kaggle 与 Lightning 的 4 vCPU 在高并发下扩展性衰减,推测主要受宿主机多租户超卖导致的上下文切换(Context Switch)及 CPU 配额(Quota)节流限制; OCI ARM 绑定的为独立物理核心,扩展曲线受多租户干扰相对较小
  • 测试局限:各实例未强制对齐底层线性代数库与依赖环境(如 OpenBLAS / MKL 编译后端差异),随机森林单次采样可能存在瞬态扰动
四、源码

import importlib.metadata as metadataimport osimport platformimport statisticsimport sysimport time
import numpy as npimport sklearnimport torchfrom joblib import cpu_countfrom sklearn.datasets import make_classificationfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.metrics import accuracy_scorefrom sklearn.model_selection import train_test_split
ORACLE_RF_SECONDS = {1: 34.124, 2: 17.737, 4: 9.503}ORACLE_TORCH_CPU_SECONDS = {1024: {1: 0.0571, 2: 0.0293, 4: 0.0158},2048: {1: 0.4531, 2: 0.2266, 4: 0.1237},4096: {1: 3.6563, 2: 1.8504, 4: 1.0573},}OFFICIAL_TARGETS = {"numpy": "2.3.5","scipy": "1.16.3","scikit-learn": "1.8.0","ISLP": "0.4.1","torch": "2.10.0",}
def installed_version(name):try:return metadata.version(name)except metadata.PackageNotFoundError:return "未安装"
def environment_report():print("=" * 72)print("环境检查")print("=" * 72)print(f"OS / 架构             : {platform.platform()} / {platform.machine()}")print(f"Python                : {sys.version.split()[0]}")print(f"逻辑 CPU ( OS )        : {os.cpu_count()}")print(f"可用 CPU ( joblib )    : {cpu_count()}")print(f"PyTorch               : {torch.version}")print(f"PyTorch 默认线程数    : {torch.get_num_threads()}")print(f"CUDA 可用             : {torch.cuda.is_available()}")if torch.cuda.is_available():print(f"GPU                   : {torch.cuda.get_device_name(0)}")print("\nISLP_labs v2.2.2 官方 requirements 相关目标版本:")for package, target in OFFICIAL_TARGETS.items():actual = installed_version(package)print(f"  {package:16} 当前={actual:18} 目标={target}")print("提示:先记录平台预装版本。不要只为版本号相同就替换 Kaggle 预装的 PyTorch ;这可能影响 GPU/CUDA 配置。")print("线程数 1/2/4 用于与 Oracle 的结果横向比较;若平台可用 CPU 少于 4 ,4 线程结果可能受资源限制。")
def random_forest_benchmark():print("\n" + "=" * 72)print("任务 A:scikit-learn 随机森林( CPU )")print("=" * 72)print("数据:40,000 个样本、40 个特征;训练集 32,000 ,测试集 8,000 ; 200 棵树。")data_start = time.perf_counter()X, y = make_classification(n_samples=40_000,n_features=40,n_informative=20,n_redundant=10,n_classes=2,random_state=42,)X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)print(f"数据准备耗时:{time.perf_counter() - data_start:.3f} 秒")results = []for n_jobs in (1, 2, 4):model = RandomForestClassifier(n_estimators=200, max_features="sqrt", random_state=42, n_jobs=n_jobs)t0 = time.perf_counter()model.fit(X_train, y_train)train_seconds = time.perf_counter() - t0t0 = time.perf_counter()pred = model.predict(X_test)predict_seconds = time.perf_counter() - t0accuracy = accuracy_score(y_test, pred)results.append((n_jobs, train_seconds, predict_seconds, accuracy))print(f"\nn_jobs={n_jobs}: 训练 {train_seconds:.3f}s | 预测 {predict_seconds:.3f}s | 准确率 {accuracy:.4%}")baseline = results[0][1]print("\n 与 Oracle 同一任务实测对比(训练时间):")for n_jobs, seconds, predict_seconds, accuracy in results:oracle = ORACLE_RF_SECONDS[n_jobs]if seconds > 0:ratio = oracle / secondslabel = f"Kaggle 约快 {ratio:.2f} 倍" if ratio > 1.01 else (f"Oracle 约快 {1/ratio:.2f} 倍" if ratio < 0.99 else "两者接近")else:label = "无法计算比例"print(f"{n_jobs} 线程 | Kaggle {seconds:.3f}s | Oracle {oracle:.3f}s | {label} | 加速 {baseline/seconds:.2f}x")return results
def pytorch_cpu_benchmark():print("\n" + "=" * 72)print("任务 B:PyTorch CPU 矩阵乘法(与 Oracle 使用相同矩阵规模)")print("=" * 72)print("dtype=float32 ;只测 CPU ;每轮使用中位数,包含一次预热但不计入耗时。")torch.manual_seed(42)torch.set_num_interop_threads(1)all_results = {}for n in (1024, 2048, 4096):print(f"\n 矩阵:{n} × {n}")a = torch.randn(n, n, dtype=torch.float32, device="cpu")b = torch.randn(n, n, dtype=torch.float32, device="cpu")repeats = 5 if n == 1024 else (3 if n == 2048 else 2)all_results[n] = {}for threads in (1, 2, 4):torch.set_num_threads(threads)_ = a @ b  # 预热samples = []for _ in range(repeats):t0 = time.perf_counter()c = a @ bsamples.append(time.perf_counter() - t0)del cseconds = statistics.median(samples)gflops = (2 * n**3) / seconds / 1e9all_results[n][threads] = secondsoracle = ORACLE_TORCH_CPU_SECONDS[n][threads]if seconds > 0:ratio = oracle / secondslabel = f"Kaggle 约快 {ratio:.2f} 倍" if ratio > 1.01 else (f"Oracle 约快 {1/ratio:.2f} 倍" if ratio < 0.99 else "两者接近")else:label = "无法计算比例"print(f"threads={threads} | 中位数 {seconds1000:.1f} ms | {gflops:.2f} GFLOP/s | Oracle {oracle1000:.1f} ms | {label}")del a, breturn all_results
def pytorch_gpu_benchmark():print("\n" + "=" * 72)print("任务 C:PyTorch GPU 矩阵乘法(仅当 CUDA 可用时运行)")print("=" * 72)if not torch.cuda.is_available():print("跳过:torch.cuda.is_available() 为 False 。若想测试 Kaggle GPU ,请在 Notebook 的 Settings / Accelerator 中选择 GPU 后重启会话。")returndevice = torch.device("cuda")print(f"GPU:{torch.cuda.get_device_name(0)}")torch.manual_seed(42)for n in (1024, 2048, 4096):a = torch.randn(n, n, dtype=torch.float32, device=device)b = torch.randn(n, n, dtype=torch.float32, device=device)repeats = 10 if n == 1024 else (5 if n == 2048 else 3)_ = a @ btorch.cuda.synchronize()samples = []for _ in range(repeats):torch.cuda.synchronize()t0 = time.perf_counter()c = a @ btorch.cuda.synchronize()  # GPU 是异步执行的,计时前后要同步samples.append(time.perf_counter() - t0)del cseconds = statistics.median(samples)gflops = (2 * n**3) / seconds / 1e9print(f"{n} × {n} | GPU 中位数 {seconds*1000:.2f} ms | {gflops:.2f} GFLOP/s")del a, btorch.cuda.empty_cache()
def main():total_start = time.perf_counter()environment_report()random_forest_benchmark()pytorch_cpu_benchmark()pytorch_gpu_benchmark()print("\n" + "=" * 72)print(f"全部测试结束(不含安装依赖):{time.perf_counter() - total_start:.2f} 秒")print("随机森林是 CPU 任务; PyTorch CPU 测试可与 Oracle 的 CPU 数据直接比较。GPU 结果是单独的可选测试。")print("环境、库版本、可用 CPU 和后台负载都可能影响成绩;请将它们作为实测参考,而不是绝对硬件排名。")
if name == "main":main()


⚠️内容来自互联网,如有侵权请点击反馈!侵权投诉
本帖共 2 条回复,登录后即可查看

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

hot.热文换一批
  1. 宇宙到底是大还是小?一张纸对折103次的厚度,宇宙已装不下
  2. 别眨眼!人类首次"看见"光子!你家灯泡里全是它!
  3. 人类至今无法彻底解释的15个顶级现象,看完敬畏万物
  4. 二十出头就显成熟?揭秘上一代人的"大人模样"背后原因
  5. 明明含有氢和氧,氢可燃氧助燃,为什么水偏偏不能燃烧?
  6. 🎉庆祝应用中心上架15个插件了,抽波优惠券![开奖时间:2026-04-26 20:00]
  7. 人类已发现外星生命?科学家:就在12亿公里外,可能以甲烷为食
  8. 又一个新游戏上线了,欢迎体验!
  9. 自来水微塑料3000万/升,煮沸后降到480万,比桶装水高还是低?
  10. 女装退货率飙至80%,商家为何挂密码锁发货?
  11. 现在这金价是不是还有余地
  12. 世界上最凶猛的10种鸟,金雕到底有多厉害?猎杀野狼轻而易举?
  13. 古人为何50岁就百病缠身?揭秘1972年7月30日“马王堆女尸”出土之谜
  14. 中国真挖到“宝”了!海水里藏45亿吨铀,美国70年难题被突破
  15. 太阳和银河系之间,还有一个神秘结构?
  16. 科学家:在人类出生前,有两种神秘的力量帮助构建了人脑
  17. 下潜到1万多米的海底,人类发现了不该出现的东西?需要引起警惕
  18. 🌱牛马论坛-每日早报-2026年10月08日
  19. 终于装上了LightSNS,然后模块一通买,还是花了上千
  20. 吃一块能顶一天?军用压缩饼干为啥抗饿?
  21. 小时候父母不让玩手机的秘密,网友亲测:经历过才懂!
  22. 牛马论坛[NIUMABBS]-行为规范准则
  23. [Day 21] - 10.26 - Tibo 又要重置了
  24. 测试
牛马论坛(niumabbs.com),一个专注于分享日常新鲜事、职场工作点滴、摸鱼乐趣与各类生活感悟的交流平台。

    关注我们

  • 加入Q群
  • 微信客服
  • QQ客服
Copyright © 2026 NIUMABBS 版权所有 All Rights Reserved. |网站地图 劰载中...
关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表