demo3_cost_predict.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #!/usr/bin/env python3
  2. """
  3. Demo 3: 端侧成本预测
  4. =====================
  5. 输入鸿蒙 Agent 配置,输出端侧推理的 token / 延迟 / 电池消耗预估。
  6. 核心信息:
  7. - 端侧模型每次推理消耗算力和电量
  8. - 多 Agent 并行 → 手机发热 → 用户投诉
  9. - lambdagent 成本分级可在编译时预估算力消耗
  10. """
  11. import sys
  12. import os
  13. sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
  14. import yaml
  15. from lambdagent.types import AgentType, LamType, TypeTag
  16. # ── 端侧模型参数(盘古小模型估算)──
  17. PANGU_LITE_PARAMS = {
  18. "tokens_per_second": 15, # 端侧推理速度 (tok/s)
  19. "avg_input_tokens": 1500, # 平均输入 token
  20. "avg_output_tokens": 400, # 平均输出 token
  21. "power_per_inference_mah": 50, # 每次推理电池消耗 (mAh)
  22. "battery_capacity_mah": 5000, # 典型手机电池容量
  23. }
  24. def estimate_pipeline_cost(config_path: str):
  25. """从 YAML 配置预测端侧执行成本"""
  26. with open(config_path, "r", encoding="utf-8") as f:
  27. cfg = yaml.safe_load(f)
  28. agent_type = cfg.get("type", "simple")
  29. model_name = cfg.get("model", {}).get("name", "unknown")
  30. # 计算 Agent 数量和步数
  31. if agent_type == "chain":
  32. steps = cfg.get("chain", {}).get("steps", [])
  33. n_agents = len(steps)
  34. n_llm_calls = n_agents # 顺序: 每个 Agent 一次 LLM 调用
  35. parallelism = 1
  36. elif agent_type == "parallel":
  37. agents = cfg.get("parallel", {}).get("agents", [])
  38. n_agents = len(agents)
  39. n_llm_calls = n_agents # 并行: 同时调用
  40. parallelism = n_agents
  41. else:
  42. n_agents = 1
  43. n_llm_calls = 1
  44. parallelism = 1
  45. max_steps = cfg.get("runtime", {}).get("max_steps", n_llm_calls)
  46. # 成本估算
  47. p = PANGU_LITE_PARAMS
  48. total_input_tokens = p["avg_input_tokens"] * n_llm_calls
  49. total_output_tokens = p["avg_output_tokens"] * n_llm_calls
  50. total_tokens = total_input_tokens + total_output_tokens
  51. if parallelism > 1:
  52. # 并行: 延迟取最长的那个,但算力翻倍
  53. latency_seconds = (p["avg_input_tokens"] + p["avg_output_tokens"]) / p["tokens_per_second"]
  54. power_mah = p["power_per_inference_mah"] * n_llm_calls
  55. else:
  56. # 顺序: 延迟累加
  57. latency_seconds = total_tokens / p["tokens_per_second"]
  58. power_mah = p["power_per_inference_mah"] * n_llm_calls
  59. battery_percent = (power_mah / p["battery_capacity_mah"]) * 100
  60. return {
  61. "config": cfg.get("agentId", "unknown"),
  62. "model": model_name,
  63. "type": agent_type,
  64. "n_agents": n_agents,
  65. "n_llm_calls": n_llm_calls,
  66. "parallelism": parallelism,
  67. "total_input_tokens": total_input_tokens,
  68. "total_output_tokens": total_output_tokens,
  69. "latency_seconds": round(latency_seconds, 1),
  70. "power_mah": power_mah,
  71. "battery_percent": round(battery_percent, 1),
  72. }
  73. def main():
  74. print("=" * 60)
  75. print("Demo 3: 端侧成本预测")
  76. print("场景: 鸿蒙 Agent 在手机上运行的算力/延迟/电池消耗")
  77. print("=" * 60)
  78. print()
  79. demo_dir = os.path.dirname(__file__)
  80. # ── 场景 A: 旅行规划 (顺序管道) ──
  81. travel_path = os.path.join(demo_dir, "harmony_travel.yaml")
  82. if os.path.exists(travel_path):
  83. print("[场景 A] 旅行规划 — 顺序管道 (Planner → Transport → Hotel)")
  84. cost = estimate_pipeline_cost(travel_path)
  85. print(f" Agent: {cost['config']}")
  86. print(f" 模型: {cost['model']}")
  87. print(f" 架构: {cost['type']} ({cost['n_agents']} Agents)")
  88. print(f" LLM 调用次数: {cost['n_llm_calls']}")
  89. print(f" 预估 Token: ~{cost['total_input_tokens']:,} (输入) + ~{cost['total_output_tokens']:,} (输出)")
  90. print(f" 端侧延迟: ~{cost['latency_seconds']}s")
  91. print(f" 电池消耗: ~{cost['battery_percent']}%")
  92. print()
  93. # ── 场景 B: IoT 智能家居 (并行) ──
  94. iot_path = os.path.join(demo_dir, "harmony_iot.yaml")
  95. if os.path.exists(iot_path):
  96. print("[场景 B] IoT 智能家居 — 并行 (Climate ∥ Light ∥ Security)")
  97. cost = estimate_pipeline_cost(iot_path)
  98. print(f" Agent: {cost['config']}")
  99. print(f" 模型: {cost['model']}")
  100. print(f" 架构: {cost['type']} ({cost['n_agents']} Agents, 并行度={cost['parallelism']})")
  101. print(f" LLM 调用次数: {cost['n_llm_calls']} (同时)")
  102. print(f" 预估 Token: ~{cost['total_input_tokens']:,} (输入) + ~{cost['total_output_tokens']:,} (输出)")
  103. print(f" 端侧延迟: ~{cost['latency_seconds']}s (并行取最长)")
  104. print(f" 电池消耗: ~{cost['battery_percent']}% (算力翻倍)")
  105. print()
  106. print(" ⚠️ 3 个 Agent 并行 → CPU 满载 → 手机发热")
  107. print(f" 💡 建议: 电量 < 20% 时自动降级为单 Agent 模式")
  108. print()
  109. # ── 对比 ──
  110. print("[对比] 仓颉编译器 vs lambdagent")
  111. print(" 仓颉: 编译通过 → 运行 → 手机发热 → 用户投诉 → 才发现")
  112. print(" lambdagent: 编译时预估成本 → 超阈值告警 → 自动降级策略")
  113. print()
  114. print("=" * 60)
  115. print("结论: 端侧算力消耗可预测 → 优化电池/发热体验")
  116. print("手机快没电时自动降级 → 用户体验不降级")
  117. print("=" * 60)
  118. if __name__ == "__main__":
  119. main()