C# 中Task的核心讲解(线程的高级用法)

mikel阅读(20)

来源: C# 中Task的核心讲解(线程的高级用法)

Task 概述

Task 是 .NET 中用于表示异步操作的类,属于 System.Threading.Tasks 命名空间。它封装了一个异步操作,提供状态管理、取消支持、延续任务等功能,是编写异步代码的核心组件之一。

Task 的核心特性

  • 异步执行

    :Task 可以在后台线程或线程池中运行,避免阻塞主线程。

  • 状态跟踪

    :提供 Status 属性(如 RanToCompletionFaultedCanceled)。

  • 结果获取

    :通过 Result 属性获取返回值(泛型 Task<T>)。

  • 取消支持

    :结合 CancellationToken 实现任务取消。

  • 延续任务

    :通过 ContinueWith 定义任务完成后的操作。


常用使用方法

创建并启动 Task

使用 Task.Run 或 Task.Factory.StartNew 启动一个后台任务:


// 1. 使用 Task.Run(最常用)
staticvoidMain(string[] args)
 {
// 1. 使用构造函数(需要手动启动)
     Task task1 = new Task(() =>
     {
         Thread.Sleep(100);
         Console.WriteLine($"hello,task1的线程ID为{Thread.CurrentThread.ManagedThreadId}");
     });
     task1.Start();

// 2. 使用 Task.Factory.StartNew
     Task task2 = Task.Factory.StartNew(() =>
     {
         Thread.Sleep(100);
         Console.WriteLine($"hello,task2的线程ID为{Thread.CurrentThread.ManagedThreadId}");
     });
//3.使用 Task.Run(最常用)
     Task task3 = Task.Run(() => 
     {
         Thread.Sleep(100);
         Console.WriteLine($"hello,task3的线程ID为{Thread.CurrentThread.ManagedThreadId}");

     });
     Console.WriteLine($"主线程ID为{Thread.CurrentThread.ManagedThreadId}");
     Console.ReadKey();
 }

执行结果如下,可以看到先输出了 “主线程ID为1”,说明了Task不会阻塞主线程,并且线程执行是无序的

我们也可以创建有返回值的Task,用法和没有返回值的基本一致,,代码如下:


Task task1 = new Task(() =>
{
    Thread.Sleep(100);
return ($"task1的线程ID为{Thread.CurrentThread.ManagedThreadId}");

});
task1.Start();

Task task2 = Task.Factory.StartNew(() =>
{
    Thread.Sleep(100);
return222;
});

Task task3 = Task.Run(() =>
{
    Thread.Sleep(100);
returntrue;
});

Console.WriteLine($"主线程ID为{Thread.CurrentThread.ManagedThreadId}");
Console.WriteLine(task1.Result);
Console.WriteLine(task2.Result);
Console.WriteLine(task3.Result);
Console.ReadKey();

执行结果如下:

task.Resut获取结果时会阻塞主线程,即如果task没有执行完成,会等待task执行完成获取到Result,所以这里是顺序执行。

等待 Task 完成

通过 WaitWaitAll 或 await 等待任务完成:

var task = Task.Run(()=>{
    Thread.Sleep(1000);
    return"完成";
});

// 阻塞等待
task.Wait();
Console.WriteLine(task.Result);

// 异步等待(需在 async 方法中使用)
string result = await task;

处理 Task 返回值

使用泛型 Task<T> 获取返回值:

Task<int> task = Task.Run(()=>{
  return 42;
});
Console.WriteLine(task.Result);// 输出 42

任务延续(ContinueWith)

在任务完成后执行后续操作:

Task.Run(()=>{
    Console.WriteLine("任务1");
}).ContinueWith(prevTask =>{
    Console.WriteLine("任务2");
});

取消 Task

通过 CancellationToken 实现任务取消:

var cts = new CancellationTokenSource();
var task = Task.Run(()=>{
while(true){
    cts.Token.ThrowIfCancellationRequested();
    Thread.Sleep(100);
}
}, cts.Token);

cts.CancelAfter(1000);// 1秒后取消

异常处理

通过 AggregateException 捕获任务异常:

try{
    Task.Run(()=>throw new Exception("错误")).Wait();
}catch(AggregateException ex){
    Console.WriteLine(ex.InnerException.Message);
}

最佳实践


  • 避免 Task.Result 或 Task.Wait 导致死锁(尤其在 UI 线程中)。


  • 使用 Task.WhenAll 并行执行多个任务:

Task<int> task1 = Task.Run(()=>1);
Task<int> task2 = Task.Run(()=>2);
int[] results = await Task.WhenAll(task1, task2);

Task 是现代 C# 异步编程的基础,合理使用可提升程序性能和响应能力。

C# async / await 用法以及和Task的关系(高级用法)

mikel阅读(16)

来源: C# async / await 用法以及和Task的关系(高级用法)

在C#5.0中,出现的async和await关键字是用于简化异步编程的强大工具。它们使得编写异步代码更加直观和易于理解。要完全理解async和await,首先需要理解它们与Task的关系。

Task 基础

在C#中,Task是表示一个异步操作的类。它可以封装一个异步操作,比如文件I/O、网络请求等。Task对象可以处于三种状态之一:未开始(Not Started)、正在运行(Running)或已完成(RanToCompletion)。
需要详细了解的可以看 上一篇文章 C# 中Task的核心讲解(线程的高级用法)

async 关键字

async关键字用于声明一个方法为异步方法。当一个方法被声明为async时,它会自动返回一个Task或Task对象,其中T是方法的返回类型。这使得你可以在不阻塞调用线程的情况下执行耗时的操作。

例如:

public async Task<int> GetDataAsync()
{
 // 模拟异步操作,比如网络请求
 await Task.Delay(10000);// 异步等待1秒
 return 42;// 返回结果
}

await 关键字

await关键字用于等待一个异步操作的完成。当在异步方法中使用await时,它会暂停当前方法的执行,直到被等待的异步操作完成。当异步操作完成后,控制流会恢复并继续执行后续代码。这允许主线程不被阻塞,从而提升应用程序的响应性和性能。

例如:

public async Task CallAsyncMethod()
{
  int result = await GetDataAsync();// 等待GetDataAsync完成
  Console.WriteLine(result);// 继续执行
}

async 和 await 的关系和作用

‌1、声明异步方法‌:使用async关键字声明一个方法为异步方法。这允许该方法的返回类型为Task或Task。
2、‌等待异步操作‌:在异步方法内部,使用await关键字等待另一个异步操作完成。这不会阻塞调用线程,允许其他操作继续执行。
3‌、简化异步编程‌:结合使用async和await,可以使得编写和处理异步代码变得更加简单和直观。

示例:完整流程,比如在Winform中

public partial class Form1:Form
{
 public Form1()
 {
   InitializeComponent();

   Task task =GetDataAsync();
   Console.WriteLine(11111);// 返回结果

}
public async Task GetDataAsync()
{
  // 模拟异步操作,比如网络请求
  await Task.Delay(10000);// 异步等待10秒
  Console.WriteLine(42234);// 返回结果
}
}

这里会先打印出11111,然后等待10秒 会在打印出 42234,并且 此期间,可以进行其它操作,比如 移动 窗口,或者 点击其它按钮等,都是不阻塞的。

例子:

namespace 异步编程
{
public partial class Form1:Form
{
 public Form1()
 {
   InitializeComponent();

   Task task =FunAsync();
   Console.WriteLine("主线程");// 返回结果

}
public async Task FunAsync()
{
   Console.WriteLine("Before calling GetDataAsync");
   await GetDataAsync();// 等待异步操作完成,才往下一行执行
   Console.WriteLine("After calling GetDataAsync");
}

/// <summary>
/// 一个耗时操作
/// </summary>
/// <returns></returns>
private Task GetDataAsync()
{
  Task task1 = new Task(()=>
 {
   Console.WriteLine("开始执行耗时操作");
   Thread.Sleep(10000);
   Console.WriteLine("结束执行耗时操作");// 返回结果
 });
  task1.Start();
 return task1;
}
}
}

运行过程

在这个例子中,当调用GetDataAsync()时,控制流会暂停在await表达式处,直到GetDataAsync()完成;而且Winform页面可以正常移动。一旦完成,控制流会继续执行到await下一行代码。这确保了即使在等待异步操作完成时,主线程也不会被阻塞

个人总结为:async / await 本身不是异步,而是用来简化异步操作的,异步还是线程干的活,常和Task配合。只要记得 哪个方法里使用await ,哪个方法会暂停往下执行,直至 await 后面跟的异步方法执行完成,才会继续往下进行;在这等待期间不影响其它操作。

分享几个Google Chrome谷歌浏览器历史版本下载网站_chrome历史版本-CSDN博客

mikel阅读(24)

来源: 分享几个Google Chrome谷歌浏览器历史版本下载网站_chrome历史版本-CSDN博客

驱动下载地址:https://registry.npmmirror.com/binary.html?path=chromedriver

文章目录
网站1
网站2
网站3
网站1
谷歌浏览器历史版本相关地址:https://www.chromedownloads.net/chrome64win/

 

网站2
谷歌浏览器历史版本相关地址:https://downzen.com/en/windows/google-chrome/versions/

 

网站3
谷歌浏览器历史版本相关地址:https://vikyd.github.io/download-chromium-history-version/#/

1、选择你的电脑系统(Windows或者Mac):

2、输入版本号,下面就会出现很多版本了,随便选个即可:

————————————————
版权声明:本文为CSDN博主「袁袁袁袁满」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yuan2019035055/article/details/136607093

Google Chrome 64bit Windows版_chrome浏览器,chrome插件,谷歌浏览器下载,谈笑有鸿儒

mikel阅读(20)

来源: Google Chrome 64bit Windows版_chrome浏览器,chrome插件,谷歌浏览器下载,谈笑有鸿儒

立即下载 Google Chrome 64bit Windows版

chrome64位windows稳定版

chrome64位windows测试版

chrome64位windows开发版

chrome64位windows金丝雀版

【零基础入门】Open-AutoGLM 完全指南:Mac 本地部署 AI 手机助理(原理+部署+优化)附上修改后代码-CSDN博客

mikel阅读(39)

来源: 【零基础入门】Open-AutoGLM 完全指南:Mac 本地部署 AI 手机助理(原理+部署+优化)附上修改后代码-CSDN博客

代码路径:
https://github.com/weidadedawei/Open-AutoGLM

目录
1. 什么是 Open-AutoGLM?
2. 核心原理解析
3. 环境准备(超详细)
4. 模型下载与部署
5. 实战操作指南
6. 性能优化详解
7. API 与进阶用法
8. 常见问题 FAQ
1. 什么是 Open-AutoGLM?
1.1 项目简介
Open-AutoGLM 是智谱 AI 开源的手机 AI 助理框架。它能让你的 Mac 变成一个”超级大脑”,通过 USB 或 WiFi 远程控制你的安卓手机,自动完成各种任务。

想象一下这些场景:

“帮我在饿了么点一份黄焖鸡米饭”
“打开微信给妈妈发消息说我今晚不回家吃饭”
“在网易云音乐搜索周杰伦的歌并播放”
“打开 B 站搜索 Python 教程”
这些以前需要你亲自动手的操作,现在只需一句话,AI 就能帮你完成!

1.2 为什么选择本地部署?
对比项 云端 API 模式 本地 MLX 模式
隐私安全 截图上传云端 数据永不出本机
运行成本 按 Token 收费 电费即成本
网络依赖 断网不可用 完全离线可用
响应延迟 网络延迟波动 本地计算稳定
1.3 适合谁?
开发者:想了解 AI Agent 如何工作
隐私敏感用户:不希望手机截图上传云端
极客玩家:想在本地玩转多模态大模型
学习者:想学习 MLX、ADB、多模态模型的实际应用
2. 核心原理解析
2.1 AI Agent 工作原理
Open-AutoGLM 采用经典的 感知-思考-行动 (Perception-Thinking-Action) 循环:

┌─────────────────────────────────────────────────────────────┐
│ Agent 工作循环 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 感 知 │ ──→ │ 思 考 │ ──→ │ 行 动 │ │
│ │ │ │ │ │ │ │
│ │ 截图 │ │ 理解状态 │ │ 点击 │ │
│ │ UI解析 │ │ 规划步骤 │ │ 滑动 │ │
│ │ App状态 │ │ 生成指令 │ │ 输入 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ ↑ │ │
│ └──────────────────────────────────┘ │
│ 循环执行 │
└─────────────────────────────────────────────────────────────┘
运行项目并下载源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2.2 三层架构详解
感知层 (Perception Layer)

感知类型 技术实现 数据格式
视觉感知 adb shell screencap -p PNG 图像
结构化感知 adb shell uiautomator dump XML 元素树
状态感知 adb shell dumpsys activity App/Activity 信息
推理层 (Reasoning Layer)

AutoGLM-Phone-9B 是一个 视觉-语言模型 (VLM):

输入: [系统提示] + [任务描述] + [手机截图]

多模态编码器 (Vision Encoder)

Transformer 推理

输出: <think>推理过程</think><answer>{“action”: “Tap”, “element”: [500, 300]}</answer>
运行项目并下载源码
1
2
3
4
5
6
7
模型会先在 <think> 标签中进行推理(类似 ChatGPT o1 的思考过程),然后在 <answer> 标签中输出具体的 JSON 操作指令。

执行层 (Execution Layer)

操作类型 ADB 命令 说明
Tap adb shell input tap x y 点击坐标
Swipe adb shell input swipe x1 y1 x2 y2 滑动
Type adb shell am broadcast -a ADB_INPUT_TEXT 输入文字
Launch adb shell am start -n package/activity 启动应用
2.3 MLX 框架介绍
MLX 是苹果公司专门为 Apple Silicon (M1/M2/M3/M4) 开发的深度学习框架:

统一内存架构:GPU 和 CPU 共享内存,无需复制数据
延迟编译:只编译实际执行的代码路径
原生 Metal 加速:充分利用 Apple GPU
对于本项目,MLX 让我们能在 Mac 上高效运行 9B 参数的多模态模型!

3. 环境准备(超详细)
3.1 系统要求
项目 最低要求 推荐配置
系统版本 macOS 13.3+ macOS 14+ (Sonoma)
芯片 M1 M1 Max / M2 Pro 及以上
内存 16GB (量化后) 32GB+
硬盘 20GB 可用空间 50GB+ SSD
Python 3.10+ 3.11
3.2 安装 Python 环境
方法 A:使用 Homebrew + pyenv(推荐)

# 1. 安装 Homebrew (如果没有)
/bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)”

# 2. 安装 pyenv
brew install pyenv

# 3. 配置 shell (以 zsh 为例)
echo ‘export PYENV_ROOT=”$HOME/.pyenv”‘ >> ~/.zshrc
echo ‘command -v pyenv >/dev/null || export PATH=”$PYENV_ROOT/bin:$PATH”‘ >> ~/.zshrc
echo ‘eval “$(pyenv init -)”‘ >> ~/.zshrc
source ~/.zshrc

# 4. 安装 Python 3.11
pyenv install 3.11.9
pyenv global 3.11.9

# 5. 验证安装
python –version # 应该显示 Python 3.11.9
运行项目并下载源码
bash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
方法 B:使用 Conda

# 1. 下载 Miniforge (适合 Apple Silicon 的 Conda)
curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh

# 2. 安装
bash Miniforge3-MacOSX-arm64.sh

# 3. 创建虚拟环境
conda create -n autoglm python=3.11
conda activate autoglm
运行项目并下载源码
bash
1
2
3
4
5
6
7
8
9
3.3 安装 ADB 工具
ADB (Android Debug Bridge) 是连接 Mac 和安卓手机的桥梁。

# 使用 Homebrew 安装
brew install Android-platform-tools

# 验证安装
adb version
运行项目并下载源码
bash
1
2
3
4
5
3.4 配置安卓手机
步骤 1:开启开发者模式

打开 设置 → 关于手机
连续点击 版本号 7 次
看到提示”您已进入开发者模式”
不同品牌手机的位置可能略有不同。华为在”关于手机”,小米在”我的设备”。

步骤 2:开启 USB 调试

返回 设置 → 系统 → 开发者选项
开启 USB 调试
开启 USB 安装 (如果有)
关闭 监控 ADB 安装应用 (如果有)
部分手机需要重启后设置才能生效!

步骤 3:连接并授权

使用数据线(不是纯充电线!)连接手机和 Mac
手机上会弹出授权窗口,勾选”始终允许”并点击确定
在终端验证连接:
adb devices
# 输出应该类似:
# List of devices attached
# ABCD1234567890 device
运行项目并下载源码
bash
1
2
3
4
3.5 安装 ADB Keyboard
ADB Keyboard 是一个特殊的输入法,允许通过 ADB 命令输入中文。

下载 APK:ADBKeyboard.apk

通过 ADB 安装:

adb install ADBKeyboard.apk
运行项目并下载源码
bash
1
设置为当前输入法:

手机上进入 设置 → 语言和输入法 → 管理键盘
启用 ADB Keyboard
验证安装:

adb shell ime list -a | grep ADB
# 应该输出: com.android.adbkeyboard/.AdbIME
运行项目并下载源码
bash
1
2
3.6 安装项目依赖
# 1. 克隆项目
git clone https://github.com/zai-org/Open-AutoGLM.git
cd Open-AutoGLM

# 2. 安装 MLX 相关依赖
pip install mlx “git+https://github.com/Blaizzy/mlx-vlm.git@main” torch torchvision transformers

# 3. 安装项目依赖
pip install -r requirements.txt
pip install -e .

# 4. 验证安装
python -c “import mlx; import phone_agent; print(‘安装成功!’)”
运行项目并下载源码
bash

1
2
3
4
5
6
7
8
9
10
11
12
13
4. 模型下载与部署
4.1 下载模型
方法 A:使用 HuggingFace CLI(推荐)

# 安装 CLI 工具
pip install -U “huggingface_hub[cli]”

# 设置国内镜像(可选,加速下载)
export HF_ENDPOINT=https://hf-mirror.com

# 下载模型(约 20GB)
huggingface-cli download –resume-download zai-org/AutoGLM-Phone-9B –local-dir ./models/AutoGLM-Phone-9B
运行项目并下载源码
bash
1
2
3
4
5
6
7
8
方法 B:使用 ModelScope(国内最快)

pip install modelscope

python -c “from modelscope import snapshot_download; snapshot_download(‘ZhipuAI/AutoGLM-Phone-9B’, local_dir=’./models/AutoGLM-Phone-9B’)”
运行项目并下载源码
bash
1
2
3
4.2 启动运行
下载完成后即可运行:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开微信”
运行项目并下载源码
bash
1
4.3 可选:4-bit 量化(推荐 16GB 内存用户)
如果你的 Mac 内存只有 16GB,或希望更快的推理速度,可以对模型进行量化:

量化效果对比:

对比项 原始模型 (FP16) 4-bit 量化
模型大小 ~20GB ~6.5GB
内存占用 需 32GB+ 16GB 即可
推理速度 较慢 提升约 3x
精度损失 基准 约 1-2%
量化步骤:

# 执行量化转换(约 15-20 分钟)
python -m mlx_vlm.convert \
–hf-path ./models/AutoGLM-Phone-9B \
-q \
–q-bits 4 \
–mlx-path ./autoglm-9b-4bit
运行项目并下载源码
bash
1
2
3
4
5
6
使用量化模型运行:

python main.py –local –model ./autoglm-9b-4bit “打开B站搜索二次元”
运行项目并下载源码
bash
1
5. 实战操作指南
5.1 基础命令
交互模式:

python main.py –local –model ./models/AutoGLM-Phone-9B

# 然后输入任务:
> 打开微信
> 搜索张三并发送消息你好
> 退出
运行项目并下载源码
bash
1
2
3
4
5
6
单任务模式:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开抖音刷5个视频”
运行项目并下载源码
bash
1
5.2 常用参数
参数 说明 示例
–local 使用本地 MLX 推理 –local
–model 模型路径 –model ./models/AutoGLM-Phone-9B
–device-id 指定设备 –device-id 192.168.1.100:5555
–lang 语言 (cn/en) –lang en
–list-apps 列出支持的应用 –list-apps
–list-devices 列出连接的设备 –list-devices
5.3 任务示例
社交通讯:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开微信给张三发消息说:下午三点开会”
运行项目并下载源码
bash
1
电商购物:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开淘宝搜索蓝牙耳机按价格排序”
运行项目并下载源码
bash
1
美食外卖:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开美团外卖点一份黄焖鸡米饭”
运行项目并下载源码
bash
1
视频娱乐:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开B站搜索Python教程”
运行项目并下载源码
bash
1
音乐播放:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开网易云音乐搜索周杰伦的晴天并播放”
运行项目并下载源码
bash
1
5.4 WiFi 远程调试
无需 USB 线也能控制手机!

步骤 1:开启无线调试

确保手机和 Mac 在同一 WiFi 下
进入 开发者选项 → 无线调试
开启无线调试,记下 IP 和端口
步骤 2:连接设备

# 连接远程设备
adb connect 192.168.1.100:5555

# 验证连接
adb devices

# 使用远程设备执行任务
python main.py –local –model ./models/AutoGLM-Phone-9B \
–device-id 192.168.1.100:5555 \
“打开抖音刷视频”
运行项目并下载源码
bash

1
2
3
4
5
6
7
8
9
10
5.5 支持的操作类型
操作 说明
Tap 点击指定坐标
Swipe 滑动屏幕
Type 输入文本
Launch 启动应用
Back 返回上一页
Home 返回桌面
Long Press 长按
Double Tap 双击
Wait 等待页面加载
Take_over 请求人工接管
6. 性能优化详解
6.1 内置优化(自动生效)
我们在代码中实现了三项关键优化:

优化 1:智能图像降采样

现代手机屏幕动辄 2K/4K,直接处理太慢。系统自动将图像长边限制在 1024 像素以内。

原始尺寸 处理后尺寸 像素减少
2400×1080 1024×460 82%
1920×1080 1024×576 72%
优化 2:KV Cache 量化

推理时启用 kv_bits=8,将 KV Cache 从 FP16 量化到 INT8:

显存占用降低约 30%
推理速度略有提升
优化 3:显存强制回收

每步推理后强制执行 mx.clear_cache() 和 gc.collect():

防止”越用越卡”
长时间运行保持稳定
6.2 手动优化建议
关闭不必要的后台应用:MLX 推理需要大量内存
使用有线连接:USB 比 WiFi 更稳定,截图传输更快
降低手机亮度:高亮度截图文件更大
定期重启模型:如果变慢了,Ctrl+C 终止后重新启动
6.3 性能参考
在 Mac Studio M1 Max (32GB) 上使用 4-bit 量化模型:

阶段 耗时
模型加载 约 30 秒
单步推理 13-18 秒
截图获取 0.5-1 秒
完整任务示例:“打开网易云音乐搜索歌曲一滴泪的时间播放”

总步数:6 步
总耗时:约 2 分 18 秒
7. API 与进阶用法
7.1 Python API 调用
from phone_agent import PhoneAgent
from phone_agent.model import ModelConfig
from phone_agent.agent import AgentConfig

# 配置模型
model_config = ModelConfig(
model_name=”./models/AutoGLM-Phone-9B”,
is_local=True,
max_tokens=3000,
temperature=0.1,
)

# 配置 Agent
agent_config = AgentConfig(
max_steps=50,
verbose=True,
lang=”cn”,
)

# 创建并运行
agent = PhoneAgent(
model_config=model_config,
agent_config=agent_config,
)

result = agent.run(“打开抖音刷3个视频”)
print(f”任务结果: {result}”)
运行项目并下载源码
python
运行

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
7.2 自定义回调函数
处理敏感操作和人工接管场景:

def my_confirmation(message: str) -> bool:
“””敏感操作确认(如支付)”””
print(f”检测到敏感操作: {message}”)
return input(“是否继续?(y/n): “).lower() == “y”

def my_takeover(message: str) -> None:
“””人工接管(如登录验证)”””
print(f”需要人工操作: {message}”)
input(“完成后按回车继续…”)

agent = PhoneAgent(
confirmation_callback=my_confirmation,
takeover_callback=my_takeover,
)
运行项目并下载源码
python
运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
7.3 批量执行任务
tasks = [
“打开微信给张三发消息:会议改到下午4点”,
“打开支付宝查看余额”,
“打开美团查看最近订单”,
]

for task in tasks:
result = agent.run(task)
print(f”完成: {task}”)
agent.reset()
运行项目并下载源码
python
运行

1
2
3
4
5
6
7
8
9
10
7.4 配置参数参考
ModelConfig 参数:

参数 类型 默认值 说明
model_name str – 模型路径
is_local bool False 使用本地推理
max_tokens int 3000 最大输出 token
temperature float 0.1 采样温度
AgentConfig 参数:

参数 类型 默认值 说明
max_steps int 100 最大执行步数
device_id str None ADB 设备 ID
lang str cn 语言
verbose bool True 显示详细输出
8. 常见问题 FAQ
Q1: 设备未找到
adb devices # 输出为空
运行项目并下载源码
bash
1
解决方案:

adb kill-server
adb start-server
adb devices
运行项目并下载源码
bash
1
2
3
常见原因:

数据线是纯充电线
没有在手机上授权
开发者选项未正确开启
Q2: 模型加载失败 / 下载中断
# 使用断点续传
huggingface-cli download –resume-download zai-org/AutoGLM-Phone-9B –local-dir ./models/AutoGLM-Phone-9B

# 或使用国内镜像
export HF_ENDPOINT=https://hf-mirror.com
运行项目并下载源码
bash
1
2
3
4
5
Q3: 内存不足 (Killed / MemoryError)
使用 4-bit 量化版本(见 4.3 节)
关闭其他应用
重启 Mac 后再试
Q4: 文本输入不工作
确认已安装 ADB Keyboard
确认已在系统中启用
验证安装:
adb shell ime list -a | grep ADB
运行项目并下载源码
bash
1
Q5: 截图失败 (黑屏)
这是系统安全机制,某些应用(支付、银行)禁止截图。模型会自动请求人工接管。

Q6: 运行变慢 / 卡顿
# 终止并重新启动
Ctrl+C
python main.py –local –model ./models/AutoGLM-Phone-9B “你的任务”
运行项目并下载源码
bash
1
2
3
Q7: WiFi 连接失败
确保手机和电脑在同一 WiFi
确保手机开启了无线调试
检查防火墙是否阻止 5555 端口
Q8: Windows/Linux 编码问题
# Windows
set PYTHONIOENCODING=utf-8

# Linux
export PYTHONIOENCODING=utf-8
————————————————
版权声明:本文为CSDN博主「伟大的大威」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010026928/article/details/155782313

手机 + Agent,这是要掀桌子!

mikel阅读(32)

来源: 手机 + Agent,这是要掀桌子!

大家好,我是技术UP主小傅哥。

这 + agent那 + agent,都是赋能,辅助提效。但手机 + agent,要掀桌子呀,这是要改变现有手机和APP厂商入口的格局。就像你开了个超市,别在你家开了个【超市入口】!

图片

智能体时代,谁也阻挡不住!

先是有豆包手机,之后GLM推出 AutoGLM-Phone-9B 模型,可以通知命令、API、语音等方式,以多模态形式,帮助用户完成手机任务。如,打开xxxAPP,搜索xxx商品,完成下单,之后通知给xxx微信伙伴,在xxx时间,进行收货也可以,告诉手机,定时定点完成xxxAPP的签到、领券,刷票抢票还可以,为老年人对于手机的xxx业务复杂的操作,进行一些列的自动化完成处理

这将是下一代手机的使用体验,也是各大厂即将争夺的智能入口。接下来,小傅哥带着大家部署下 AutoGLM 模型,以及讲解如何配置使用和最终的效果。

目前 AutoGLM 还是面向研发使用的阶段,不是直接可以调用的 API,所以要自己部署。不过以后肯定会更加方便,也会附带的提供对应的产品。也有可能出新安卓/IOS+agent的手机系统。路已经开了,看谁跑的快吧!

一、模型介绍

官网:https://github.com/zai-org/Open-AutoGLM

图片

Phone Agent 是一个基于 AutoGLM 构建的手机端智能助理框架,它能够以多模态方式理解手机屏幕内容,并通过自动化操作帮助用户完成任务。系统通过 ADB(Android Debug Bridge)来控制设备,以视觉语言模型进行屏幕感知,再结合智能规划能力生成并执行操作流程。用户只需用自然语言描述需求,如“打开小红书搜索美食”,Phone Agent 即可自动解析意图、理解当前界面、规划下一步动作并完成整个流程。系统还内置敏感操作确认机制,并支持在登录或验证码场景下进行人工接管。同时,它提供远程 ADB 调试能力,可通过 WiFi 或网络连接设备,实现灵活的远程控制与开发。

二、安装教程

1. 环境要求

  • Python 3.10+ – 如果你是手动配置环境,可以参考https://bugstack.cn/md/algorithm/model/2023-05-21-chatglm-6b.html
  • GPU 24G * 2 显卡(单卡24G部署,成功概率低)推荐具备 AI 能力的云服务器,可以减少很多基础环境的配置。如:autodl.com
  • 安卓手机一台 + 数据线(不能只是充电功能的线),设置-关于手机-版本号 然后连续快速点击 10 次左右,直到弹出弹窗显示“开发者模式已启用”。启用开发者模式之后,会出现 设置-开发者选项-USB 调试,勾选启用。(如果手机不是这样的,可以百度搜下设置)
  • AutoGLM-Phone-9B/AutoGLM-Phone-9B-Multilingual 模型镜像地址:https://huggingface.co/zai-org/AutoGLM-Phone-9B/tree/main
  • ADB (Android Debug Bridge) 桥接测试包 下载地址:https://developer.Android.com/tools/releases/platform-tools?hl=zh-cn – 下载后配置路径 export PATH=${PATH}:~/Downloads/platform-tools Windows 电脑参考第三方教程:https://blog.csdn.net/x2584179909/article/details/108319973
  • ADB Keyboard 安卓手机输入法,用于连接桥接测试包 下载地址:https://github.com/senzhk/ADBKeyBoard/blob/master/ADBKeyboard.apk – 安装后在手机设置-输入法 或者 设置-键盘列表 中启用 ADB Keyboard 才能生效

接下来介绍,各个环境配置以及验证使用。只想看效果的,可以翻看到最后(使用效果)。

2. 算力部署

目前具备 AI 算力的服务器(支持小时购买的,关机不收费);

  • www.autodl.com – 推荐 vGPUT-48GB,推荐 717机、708机
  • www.ucloud.cn
  • https://gcs-console.jdcloud.com/instance/create?region=cn-central-xy1  – 2*24GB
图片

注意,选择2卡,单卡24G的,否则大概率会失败。

2.1 创建实例(autodl)

2.1.1 创建选择

地址:https://www.autodl.com/create

2.1.2 创建完成

地址:https://www.autodl.com/console/instance/list – 控制台

图片
  • 创建并开机后,稍等即可看到GPU服务运行。
  • 注意,蓝色字 JupyterLab 是你登录地址,可以进入控制台部署模型。

其他的 GPU 服务器也都类似,如果使用的纯白 GPU 服务器,需要自己安装各种环,可参考;境。https://bugstack.cn/md/algorithm/model/2023-05-21-chatglm-6b.html

2.2 模型部署

2.2.1 进入终端
图片
  • 注意,进入后,要把服务和软件安装到 /root/autodl-tmp 下,否则系统盘安装满了,就不能运行了。
2.2.2 拉取代码
图片
  • 进入到 /root/autodl-tmp  拉取项目工程代码 git clone https://github.com/zai-org/Open-AutoGLM.git
2.2.3 更新文件(requirements.txt)
图片
Pillow>=12.0.0
openai>=2.9.0

# For Model Deployment
# Linux 云服务器环境下可以正常安装这些包
transformers>=4.30.0
vllm>=0.12.0

# Optional: sglang (如果需要的话)
# sglang>=0.5.6.post1

# Optional: for development
pytest>=7.0.0
pre-commit>=4.5.0
black>=23.0.0
mypy>=1.0.0
  • 这份文件需要更新下,默认是关闭的。
2.2.4 安装依赖
图片
pip install -r requirements.txt 
pip install -e .
  • 设置镜像源;pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
  • cd Open-AutoGLM 以此执行安装脚本。这个过程需要一段时间。如果有失败,可以重复执行脚本。
2.2.5 下载模型

下载模型是为了启动 Open-AutoGLM,如果不手动下载,默认执行脚本速度比较慢,同时可能把文件安装到系统盘中。

图片
  • 官网地址:https://huggingface.co/zai-org/AutoGLM-Phone-9B/tree/main

  • 镜像地址:https://modelscope.cn/models/ZhipuAI/AutoGLM-Phone-9B – 【下载模型】里面有对应的使用说明

图片

使用说明:

  • 在下载前,请先通过如下命令安装ModelScope pip install modelscope
  • 指定路径,下载完整模型库 modelscope download --model ZhipuAI/AutoGLM-Phone-9B --local_dir ./AutoGLM-Phone-9B
2.2.6 模型部署

脚本说明 – 固定大小的参数不能修改

python3 -m vllm.entrypoints.openai.api_server \
 --served-model-name autoglm-phone-9b \
 --allowed-local-media-path /   \
 --mm-encoder-tp-mode data \
 --mm_processor_cache_type shm \
 --mm_processor_kwargs "{\"max_pixels\":5000000}" \
 --max-model-len 25480  \
 --chat-template-content-format string \
 --limit-mm-per-prompt "{\"image\":10}" \
 --model /root/autodl-tmp/Open-AutoGLM/AutoGLM-Phone-9B \
 --port 6008
图片
  • model 由 Open-AutoGLM 默认的 zai-org/AutoGLM-Phone-9B 从 https://huggingface.co/zai-org/AutoGLM-Phone-9B/tree/main 下载,修改为已经下载好的本地的路径地址。
  • port 修改为 6008 端口,因为 autodl.com 算力指定的自定义服务,对外暴漏的端口有 6008、6006 部署后,用 https://uu835267-800d-24be97d2.westc.gpuhub.com:8443 访问服务。

执行脚本

图片
2.2.7 验证模型
图片
curl https://cb869967ef619cf1-8000.cn-south-1.gpu-instance.ppinfra.com/v1/chat/completions -H "Content-Type: application/json" -d '{
  "model": "autoglm-phone-9b",
  "messages": [
    {
      "role": "user",
      "content": "打开抖音,连刷5个视频,给第4个视频点赞,第5个视频收藏"
    }
  ]
}'
  • 这个API和 GPT 一样的格式,可以访问接口。
# 交互模式
python main.py --base-url https://cb869967ef619cf1-8000.cn-south-1.gpu-instance.ppinfra.com/v1 --model "autoglm-phone-9b"

# 指定模型端点
python main.py --base-url https://cb869967ef619cf1-8000.cn-south-1.gpu-instance.ppinfra.com/v1 "打开美团搜索附近的火锅店"

# 使用英文 system prompt
python main.py --lang en --base-url https://cb869967ef619cf1-8000.cn-south-1.gpu-instance.ppinfra.com/v1 "Open Chrome browser"

# 列出支持的应用
python main.py --list-apps
  • 根据你部署的模型, 设置 –base-url 和 –model 参数,之后本地就可以验证模型了。

3. ADB (Android Debug Bridge) – 电脑安装

3.1 安装环境

  1. 下载官方 ADB 安装包,并解压到自定义路径,地址:https://developer.android.com/tools/releases/platform-tools?hl=zh-cn
  2. 配置环境变量
  • MacOS 配置方法:在 Terminal 或者任何命令行工具里
# 假设解压后的目录为 ~/Downlaods/platform-tools。如果不是请自行调整命令。
export PATH=${PATH}:~/Downloads/platform-tools
  • Windows 配置方法:可参考 第三方教程 进行配置。

3.2 验证脚本

(base) fuzhengwei@ZBMac-GV47H1GXD Open-AutoGLM % adb devices
List of devices attached
94343646   device

(base) fuzhengwei@ZBMac-GV47H1GXD Open-AutoGLM % 
  • 此时你的电脑USB,链接了手机,会显示出设备ID(如果没显示,检查下数据线等)

4. Android 7.0+ 的设备或模拟器

4.1 开启调试模式

  1. 开发者模式启用:通常启用方法是,找到 设置-关于手机-版本号 然后连续快速点击 10 次左右,直到弹出弹窗显示“开发者模式已启用”。不同手机会有些许差别,如果找不到,可以上网搜索一下教程。

  2. USB 调试启用:启用开发者模式之后,会出现 设置-开发者选项-USB 调试,勾选启用

  3. 部分机型在设置开发者选项以后, 可能需要重启设备才能生效. 可以测试一下: 将手机用USB数据线连接到电脑后, adb devices 查看是否有设备信息, 如果没有说明连接失败.

4.2 安装 ADB Keyboard(用于文本输入)

下载 安装包 并在对应的安卓设备中进行安装。 注意,安装完成后还需要到 设置-输入法 或者 设置-键盘列表 中启用 ADB Keyboard 才能生效

图片

安装包地址:https://github.com/senzhk/ADBKeyBoard/blob/master/ADBKeyboard.apk – 可以下载好传到手机也可以

三、测试验证

1. 使用说明

图片
  • 整个的过程为,你通过命令调用LLM Phone,之后模型返回的结果,通过 ADB 方式,调用调试模式的安卓机,完成各项 APP 应用的操作。

2. 支持应用

图片

3. 使用效果

图片
python main.py --device-id 94343646 --base-url https://uu835267-800d-0124cb32.westc.gpuhub.com:8443/v1 --model "autoglm-phone-9b" "打开抖音,刷视频"
  • device-id 94343646 就是 adb 列出来的设备ID,base-url 是你的服务地址,之后可以自行验证,测试各种 APP 的启动,使用等。
  • 像是一些没有的预设的应用以及应用里的流程,他还会截图屏幕,自动分析和使用。也可以是打开其他APP,并执行一些列的流程操作。

四、其他资料

📢 接下来,在phone + agent 这个方向,将有越来越多的模型和产品。检索:https://github.com/search?q=phone%20agent&type=repositories

图片
  • https://github.com/mobile-next/mobile-mcp
  • https://device-farm.com/doc/
  • https://droidrun.ai/
  • https://github.com/CherryHQ/cherry-studio-app
  • https://github.com/minitap-ai/mobile-use

Google AdSense收入$10美元后的收款账号身份验证操作指南 - 阿小信的博客

mikel阅读(47)

来源: Google AdSense收入$10美元后的收款账号身份验证操作指南 – 阿小信的博客

前不久,我使用公司身份注册了一个全新的 Google AdSense 账号,并开发了一个全新的网站成功接入 AdSense 开始赚美元广告费。在网站上线差不多 1 个月的时间,账号累计收入达到了 10 美元。AdSense 账户累计 $10 金额后会触发一个身份验证,这个验证非常关键!只有通过了 Google AdSense 的这个收款身份验证,才能在后续账户收入达到 100 美元时顺利接 Google AdSense 的美元汇款。

这几天一直比较忙,收到邮件后一直没来得及去完成这个操作,刚好马上国庆了又加上今天感冒中,决定放松一下不搞开发了,专门写写文章。这篇文章就专门记录我是如何完成 Google AdSense 收款身份验证的,如果你也是跟我一样新账号刚起步,应该是有一定参考价值的。

注意:自 Google 首次要求验证身份之日起,有 45 天的时间可以提交所需证件。45 天后,如果未提供相关证件,或者提供的证件无法验证身份,那么 Google 将停止在网页上展示广告。

前情提要

  1. 关于我为什么有了个人身份的 AdSense 账号还要注册一个企业账号: 「至暗时刻」失去收入的一周:Google AdSense 身份验证失败,账号被停用!
  2. 如果你也想要开通一个 Google AdSense  账号: Google AdSense 新手接入教程:手把手教你用网站赚取美元收入
  3. 新 AdSense 账号的第一个里程碑: 【一人公司里程碑】全新企业 AdSense 账号历经 28 天,单日收入终于达到了 1 美元——正式进入 1 美元俱乐部!
  4. 新账号当前遇到的问题: 关于 Google AdSense 账号因无效流量被限制广告投放的问题说明与记录

邮件内容回顾

首先我们看两封 AdSense 发来的邮件内容:

这封邮件的收件时间是 2025 年 9 月 21 日 16:52,我的 AdSense 账户收入达到$10 的当天没多久就收到了这封邮件。重点已经用红框标注了。但还是再强调一下,验证是需要填写地址信息,最好一定要用身份证(营业执照)上的地址,否则可能碰上我之前的“至暗时刻”

Google 的验证它只能对比我们的证件地址和填写的地址是否一致,如果填写的地址无法出具对应的具有法律效应的证件来证明就无法通过验证。而身份证(个人)是最方便提供的证明文件。

直接点击邮件中的「立即验证」蓝色按钮就可以登录 AdSense 进行资料提交了。

收到这封邮件后,在 AdSense 页面上也会有红色警告:「请采取行动:您的 AdSense 收款账号中有一些需要核实的信息

点击「前往“收款”页面」或者点击侧边栏菜单中的「收款」-「收款信息」也可以进行验证。

第二封邮件是 2025 年 9 月 23 日 22:21 收到的,这主要是一封$10 成就达成的邮件,里面有一些操作指引:

正如邮件中说的:只要收入达到 100 美元的支付最低限额,我们就会按月收到 Google AdSense 的付款。而 10 美元是验证收款账号身份信息验证的最低限额。

如何进行 Google AdSense 收款账号身份信息验证?

下面我们开始进行 AdSense 收款账号信息验证。通过 AdSense 页面点击那个容易让人产生 PTSD 的红色警告通知前往收款页面,你将会看到一个更加让人 PTSD 发作的大红色警告 ⚠️:

点击上面的「立即验证」按钮,弹出提示框:

因为我是这个是以「公司身份」注册的账号,因此 AdSense 会提示我准备营业执照和本人身份证,如果是「个人身份」注册的账号就只需准备身份证就可以了。

勾选「同意」,并点击蓝色的「开始验证」按钮。下面的步骤是按公司身份的操作截图记录的,个人身份的差不多,按照他的提示上传资料一步一步操作就可以了。

公司身份先要上传公司的注册文件,直接点击「上传」,传我们的营业执照原件照片。注意照片要清晰、完整。

上传后,点击「下一步」:

姓名必须和身份证上一致,ID 类型选择「居民身份证」,上传我们的身份证正反面照片,同样要求完整清晰。

⚠️ 我觉得这里对于「公司类型」的账号姓名是否必须是营业执照上法定代表人的姓名有点疑问。我认为这里的姓名是要填法定代表人姓名的,不然 AdSense 可能无法进行关联。因为我也是第一次操作公司身份的账号,我的营业执照上的法定代表人就是我自己,我不确定这里是否可以上传其他人的身份证。最好保持一致,使用法定代表人的身份证信息,避免不必要的麻烦,毕竟审核申请次数有限,多一次失败就多一个风险。

继续点击「下一步」,填写地址信息,注意,完全按照身份证上的地址进行填写:

深入探索
验证
adsense
邮件
Adsense
AdSense
Google AdSense
身份验证
电子邮件
鉴权
Google-AdSense

最后,点击「提交」即可:

操作还是比较简单的,主要是信息填写要准确。提交后需要等待审核,如果不通过会被退回,审核结果需要等待几天。

最后总结一下,最重要的就是地址容易搞错,但都使用证件上的地址做到 AdSense 有证件可对比大概率就是没问题的。再次强调一下哦,和证件信息保持一致非常重要!!!我在这上面吃过亏的 T_T

这篇文章写于 9 月 30 日,后续如果有成功/失败的情况,我会更新。

本文就到这里,提前祝大家国庆节快乐!


后续更新:

10 月 7 日,收到了「Google AdSense:身份验证成功 」的邮件通知。邮件内容:

已验证您的身份。请登录您的 Google AdSense 账号,若尚未设置主要付款方式,请进行设置。

身份验证通过后,在「收款」-「收款信息」中就可以添加支付方式了。

AdSense添加支付方式

相关阅读: Google AdSense 国内如何收款?中国大陆银行电汇方式接收谷歌广告付款操作指南

10 月 8 日收到「请在 AdSense 或 AdSense YouTube 广告账号中验证您的收款地址」的邮件通知。邮件内容:

我们于 十月 08, 2025 给您在 AdSense 或 AdSense YouTube 广告账号中向我们提供的收款地址寄去了一个 PIN 码,即个人识别码。

您在收到 PIN 码邮件后,请点击本电子邮件中的验证您的地址,然后在验证页面上输入您的 PIN 码。您也可以登录自己的 AdSense 或 AdSense YouTube 广告账号,直接在验证页面上完成这些步骤。

重要提示: 如果在我们给您寄去第一个 PIN 码之日起的 4 个月内,您未使用该 PIN 码验证您的地址,我们将停止在您的网站上投放广告。

遇到了 PIN 码方面的问题?

通常需要等待 3 周时间,才能收到邮寄的 PIN 码。为避免出现任何 PIN 码递送问题,请确保您向我们提供的付款地址正确无误。在此提供几点提示:

  • 在所有付款地址字段中请使用相同的语言
  • 确认您本地的邮局能够识别您的地址
  • 与相关的邮寄服务商或邮局确认您的邮件未转寄到其他地址

如果需要,您可以按照以下步骤更改付款地址:

  1. 在您的 AdSense 或 AdSense YouTube 广告账号中,前往您的收款资料。
  2. 点击“姓名和地址”旁边的图标。
  3. 更新您的付款地址。
  4. 点击“保存”。

从我们给您寄出上一个 PIN 码的时间算起,您可以在 3 周后申请新的 PIN 码。

此时在「收款」-「验证检查」中就能看到「地址验证」中的 PIN 码输入框。等我们收到 PIN 码后填入并提交即可。PIN 是一个空的挂号信,撕开就能看到里面的 PIN 码。

AdSense PIN码验证

这里注意的是,PIN 码邮寄的地址不会单独填写,而是直接邮寄到你账号注册时填写的地址(个人账号是身份证地址/组织账号是营业执照的注册地址),如果地址不能接收 PIN 码可能需要先更新地址。

相关阅读:

【AI】智谱AutoGLM部署教程:AutoDL云服务器+本地PhoneAgent配置 | 慕雪的寒舍

mikel阅读(133)

来源: 【AI】智谱AutoGLM部署教程:AutoDL云服务器+本地PhoneAgent配置 | 慕雪的寒舍

1. 引言
开源地址:https://github.com/zai-org/Open-AutoGLM

一般情况下呢,这里得要介绍一下这个模型,背景信息啊,什么什么的。但慕雪最近很忙没时间写,直接跳过步入正题吧!

总而言之言而总之,这是智谱在25年12月9日开源的,一个专门为手机UI自动化操作开发的大模型,在今年早些时候AutoGLM的手机App就已经上线并可以通过里面的云端虚拟手机进行测试。现在,智谱把模型和本地Agent框架PhoneAgent一并开源,让我们可以自己部署AutoGLM并将其运用到各类UI自动化操作上。

 

因为是自部署的,数据都在你本地,也就不用担心大模型云端操作的隐私泄露问题了。

2. AutoDL部署AutoGLM模型
2.1. 创建镜像
AutoDL:https://www.autodl.com/home

根据官方在issue里面的回复,AutoGLM模型使用24G显存勉强可以运行,但实际上会占用27G的显存+共享内存,所以,需要在AutoDL上选一个32GB或48GB显存的服务器,cuda版本为12.8以上的,镜像选择PyTorch 2.8.0、Python 3.12(ubuntu22.04)、CUDA 12.8,就可以了。

 

创建镜像并开机之后,可以用ssh工具连这个服务器,也可以直接用控制台里面的jupyterLab链接,jupyterLab本身就带了终端持久运行的能力,不再需要我们安装tmux等其他守护进程工具了。

 

2.2. 下载模型
因为AutoDL是境内服务器,所以推荐去阿里的魔搭社区上下载模型:https://modelscope.cn/models/ZhipuAI/AutoGLM-Phone-9B

下载方式在魔搭社区上也有教程,执行如下命令即可。注意,在AutoDL上一定要进入/root/autodl-tmp数据盘进行操作,否则模型会直接把系统盘塞满,影响系统运行了。

SH
1
2
3
pip install modelscope
# 下载模型到本地,注意一定要有–local_dir参数
modelscope download –model ZhipuAI/AutoGLM-Phone-9B –local_dir /root/autodl-tmp/autoglm-phone-9b

模型大约20GB,在AutoDL上下载大概需要半个小时,耐心等待一下吧。

2.3. 配置vllm运行环境
等待模型下载期间也别闲着,开另外一个终端配置一下vllm的运行环境。

AutoGLM依赖于vllm 0.12.0和transformers 5.0.0rc0,我们可以创建一个conda环境来安装。

vllm 0.12.0在官方release中说明强依赖pytorch 3.9.0和cuda 12.9,但实测在AutoDL的cuda 12.8的环境里面是能可以正常运行无报错的。

执行如下命令,创建一个conda虚拟环境

SH
1
2
3
4
# 创建虚拟环境
conda create -n vllm python=3.12 -y
# 初始化
conda init
首次执行完毕conda init之后,会提示你开另外一个新终端,开一个新终端之后,执行如下命令

SH
1
2
3
conda init
# 激活刚刚创建的虚拟环境
conda activate vllm
执行完毕后,我们就已经进入刚刚新创建的虚拟环境里面了,执行下面两个命令即可。AutoDL的镜像已经默认设置了阿里pypi源,不需要我们修改镜像源了。

SH
1
2
pip install vllm==0.12.0 # 一定要先安装这个
pip install transformers==5.0.0rc0
注意,一定需要先安装vllm,然后再安装transformers[1],安装transformers==5.0.0rc0的时候会出现依赖不匹配的报错,因为vllm 0.12.0依赖的是4.x版本的transformers。可以直接忽略这个依赖版本不匹配的报错,智谱官方在issue里面提到了是能够兼容的,实测也确实OK。

 

其实不安装transformers==5.0.0rc0我也试过,模型也能运行,似乎也没啥问题。但是控制台会有加载解析器正则错误的告警,估计这就是截图里面提到的“新写法”导致的问题了。所以还是老实安装升级吧!

安装完毕这俩库之后,环境就搞定了,可以运行模型了!(当然得等模型下完了才行)

2.4. 运行模型
使用AutoGLM仓库里面给出的vllm命令,运行模型。注意这个命令需要修改我们下载好的模型本地路径,和端口号。AutoDL平台上只有6006和6008端口号是被映射到公网上的,其他端口号都不能使用。

另外,AutoDL租用的服务器提供外网服务需进行实名认证,请确保你的大模型服务不会被滥用生成违规违禁内容,避免罪责到你身上。

SH
1
2
3
4
5
6
7
8
9
10
11
12
# 修改最后的–model模型本地路径和–port绑定端口号
python3 -m vllm.entrypoints.openai.api_server \
–served-model-name autoglm-phone-9b \
–allowed-local-media-path / \
–mm-encoder-tp-mode data \
–mm_processor_cache_type shm \
–mm_processor_kwargs “{\”max_pixels\”:5000000}” \
–max-model-len 25480 \
–chat-template-content-format string \
–limit-mm-per-prompt “{\”image\”:10}” \
–model /root/autodl-tmp/autoglm-phone-9b \
–port 6006
执行这个命令后,vllm就会开始运行并加载模型,出现服务已上线,就是模型加载成功了。

 

回到控制台,点击自定义服务

 

把这里的6006端口号映射的URL复制一份,输入到浏览器里面。如果出现json的返回信息,且终端里面出现了请求日志,那就是模型服务部署成功了!

 

 

2.5. 完整模型加载日志
完整的模型加载日志
PLAINTEXT
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
(vllm) root@autodl-container-50604192c4-d9d01c36:~/autodl-tmp# # 修改最后的–model模型本地路径和–port绑定端口号
python3 -m vllm.entrypoints.openai.api_server \
–served-model-name autoglm-phone-9b \
–allowed-local-media-path / \
–mm-encoder-tp-mode data \
–mm_processor_cache_type shm \
–mm_processor_kwargs “{\”max_pixels\”:5000000}” \
–max-model-len 25480 \
–chat-template-content-format string \
–limit-mm-per-prompt “{\”image\”:10}” \
–model /root/autodl-tmp/autoglm-phone-9b \
–port 6006
(APIServer pid=1433) INFO 12-10 22:50:46 [api_server.py:1772] vLLM API server version 0.12.0
(APIServer pid=1433) INFO 12-10 22:50:46 [utils.py:253] non-default args: {‘port’: 6006, ‘chat_template_content_format’: ‘string’, ‘model’: ‘/root/autodl-tmp/autoglm-phone-9b’, ‘allowed_local_media_path’: ‘/’, ‘max_model_len’: 25480, ‘served_model_name’: [‘autoglm-phone-9b’], ‘limit_mm_per_prompt’: {‘image’: 10}, ‘mm_processor_kwargs’: {‘max_pixels’: 5000000}, ‘mm_processor_cache_type’: ‘shm’, ‘mm_encoder_tp_mode’: ‘data’}
(APIServer pid=1433) Unrecognized keys in `rope_parameters` for ‘rope_type’=’default’: {‘partial_rotary_factor’, ‘mrope_section’}
(APIServer pid=1433) INFO 12-10 22:50:46 [model.py:637] Resolved architecture: Glm4vForConditionalGeneration
(APIServer pid=1433) INFO 12-10 22:50:46 [model.py:1750] Using max model len 25480
(APIServer pid=1433) INFO 12-10 22:50:46 [scheduler.py:228] Chunked prefill is enabled with max_num_batched_tokens=2048.
(EngineCore_DP0 pid=1485) INFO 12-10 22:50:55 [core.py:93] Initializing a V1 LLM engine (v0.12.0) with config: model=’/root/autodl-tmp/autoglm-phone-9b’, speculative_config=None, tokenizer=’/root/autodl-tmp/autoglm-phone-9b’, skip_tokenizer_init=False, tokenizer_mode=auto, revision=None, tokenizer_revision=None, trust_remote_code=False, dtype=torch.bfloat16, max_seq_len=25480, download_dir=None, load_format=auto, tensor_parallel_size=1, pipeline_parallel_size=1, data_parallel_size=1, disable_custom_all_reduce=False, quantization=None, enforce_eager=False, kv_cache_dtype=auto, device_config=cuda, structured_outputs_config=StructuredOutputsConfig(backend=’auto’, disable_fallback=False, disable_any_whitespace=False, disable_additional_properties=False, reasoning_parser=”, reasoning_parser_plugin=”, enable_in_reasoning=False), observability_config=ObservabilityConfig(show_hidden_metrics_for_version=None, otlp_traces_endpoint=None, collect_detailed_traces=None, kv_cache_metrics=False, kv_cache_metrics_sample=0.01), seed=0, served_model_name=autoglm-phone-9b, enable_prefix_caching=True, enable_chunked_prefill=True, pooler_config=None, compilation_config={‘level’: None, ‘mode’: <CompilationMode.VLLM_COMPILE: 3>, ‘Debug_dump_path’: None, ‘cache_dir’: ”, ‘compile_cache_save_format’: ‘binary’, ‘backend’: ‘inductor’, ‘custom_ops’: [‘none’], ‘splitting_ops’: [‘vllm::unified_attention’, ‘vllm::unified_attention_with_output’, ‘vllm::unified_mla_attention’, ‘vllm::unified_mla_attention_with_output’, ‘vllm::mamba_mixer2’, ‘vllm::mamba_mixer’, ‘vllm::short_conv’, ‘vllm::linear_attention’, ‘vllm::plamo2_mamba_mixer’, ‘vllm::gdn_attention_core’, ‘vllm::kda_attention’, ‘vllm::sparse_attn_indexer’], ‘compile_mm_encoder’: False, ‘compile_sizes’: [], ‘inductor_compile_config’: {‘enable_auto_functionalized_v2’: False, ‘combo_kernels’: True, ‘benchmark_combo_kernel’: True}, ‘inductor_passes’: {}, ‘cudagraph_mode’: <CUDAGraphMode.FULL_AND_PIECEWISE: (2, 1)>, ‘cudagraph_num_of_warmups’: 1, ‘cudagraph_capture_sizes’: [1, 2, 4, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248, 256, 272, 288, 304, 320, 336, 352, 368, 384, 400, 416, 432, 448, 464, 480, 496, 512], ‘cudagraph_copy_inputs’: False, ‘cudagraph_specialize_lora’: True, ‘use_inductor_graph_partition’: False, ‘pass_config’: {‘fuse_norm_quant’: False, ‘fuse_act_quant’: False, ‘fuse_attn_quant’: False, ‘eliminate_noops’: True, ‘enable_sp’: False, ‘fuse_gemm_comms’: False, ‘fuse_allreduce_rms’: False}, ‘max_cudagraph_capture_size’: 512, ‘dynamic_shapes_config’: {‘type’: <DynamicShapesType.BACKED: ‘backed’>}, ‘local_cache_dir’: None}
(EngineCore_DP0 pid=1485) INFO 12-10 22:50:57 [parallel_state.py:1200] world_size=1 rank=0 local_rank=0 distributed_init_method=tcp://172.17.0.10:47959 backend=nccl
(EngineCore_DP0 pid=1485) INFO 12-10 22:50:58 [parallel_state.py:1408] rank 0 in world size 1 is assigned as DP rank 0, PP rank 0, PCP rank 0, TP rank 0, EP rank 0
(EngineCore_DP0 pid=1485) Using a slow image processor as `use_fast` is unset and a slow processor was saved with this model. `use_fast=True` will be the default behavior in v4.52, even if the model was saved with a slow processor. This will result in minor differences in outputs. You’ll still be able to use a slow processor with `use_fast=False`.
(EngineCore_DP0 pid=1485) Keyword argument `max_pixels` is not a valid argument for this processor and will be ignored.
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:05 [gpu_model_runner.py:3467] Starting to load model /root/autodl-tmp/autoglm-phone-9b…
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:05 [cuda.py:411] Using FLASH_ATTN attention backend out of potential backends: [‘FLASH_ATTN’, ‘FLASHINFER’, ‘TRITON_ATTN’, ‘FLEX_ATTENTION’]
Loading safetensors checkpoint shards: 0% Completed | 0/5 [00:00<?, ?it/s]
Loading safetensors checkpoint shards: 20% Completed | 1/5 [00:00<00:00, 4.26it/s]
Loading safetensors checkpoint shards: 40% Completed | 2/5 [00:01<00:02, 1.43it/s]
Loading safetensors checkpoint shards: 60% Completed | 3/5 [00:02<00:01, 1.15it/s]
Loading safetensors checkpoint shards: 80% Completed | 4/5 [00:03<00:00, 1.03it/s]
Loading safetensors checkpoint shards: 100% Completed | 5/5 [00:04<00:00, 1.06s/it]
Loading safetensors checkpoint shards: 100% Completed | 5/5 [00:04<00:00, 1.07it/s]
(EngineCore_DP0 pid=1485)
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:10 [default_loader.py:308] Loading weights took 4.87 seconds
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:11 [gpu_model_runner.py:3549] Model loading took 19.2562 GiB memory and 5.143751 seconds
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:11 [gpu_model_runner.py:4306] Encoder cache will be initialized with a budget of 18622 tokens, and profiled with 1 video items of the maximum feature size.
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:22 [backends.py:655] Using cache directory: /root/.cache/vllm/torch_compile_cache/19b1386448/rank_0_0/backbone for vLLM’s torch.compile
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:22 [backends.py:715] Dynamo bytecode transform time: 7.25 s
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:22 [backends.py:257] Cache the graph for dynamic shape for later use
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:29 [backends.py:288] Compiling a graph for dynamic shape takes 6.80 s
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:30 [monitor.py:34] torch.compile takes 14.05 s in total
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:31 [gpu_worker.py:359] Available KV cache memory: 19.17 GiB
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:32 [kv_cache_utils.py:1286] GPU KV cache size: 502,496 tokens
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:32 [kv_cache_utils.py:1291] Maximum concurrency for 25,480 tokens per request: 19.72x
Capturing CUDA graphs (mixed prefill-decode, PIECEWISE): 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 51/51 [00:03<00:00, 16.86it/s]
Capturing CUDA graphs (decode, FULL): 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 35/35 [00:01<00:00, 23.12it/s]
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:37 [gpu_model_runner.py:4466] Graph capturing finished in 5 secs, took 0.69 GiB
(EngineCore_DP0 pid=1485) INFO 12-10 22:51:37 [core.py:254] init engine (profile, create kv cache, warmup model) took 26.32 seconds
(APIServer pid=1433) INFO 12-10 22:51:40 [api_server.py:1520] Supported tasks: [‘generate’]
(APIServer pid=1433) INFO 12-10 22:51:40 [api_server.py:1847] Starting vLLM API server 0 on http://0.0.0.0:6006
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:38] Available routes are:
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /openapi.json, Methods: GET, HEAD
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /docs, Methods: GET, HEAD
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /docs/oauth2-redirect, Methods: GET, HEAD
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /redoc, Methods: GET, HEAD
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /health, Methods: GET
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /load, Methods: GET
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /pause, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /resume, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /is_paused, Methods: GET
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /tokenize, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /detokenize, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v1/models, Methods: GET
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /version, Methods: GET
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v1/responses, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v1/responses/{response_id}, Methods: GET
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v1/responses/{response_id}/cancel, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v1/messages, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v1/chat/completions, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v1/completions, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v1/audio/transcriptions, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v1/audio/translations, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /scale_elastic_ep, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /is_scaling_elastic_ep, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /inference/v1/generate, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /ping, Methods: GET
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /ping, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /invocations, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /metrics, Methods: GET
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /classify, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v1/embeddings, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /score, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v1/score, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /rerank, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v1/rerank, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /v2/rerank, Methods: POST
(APIServer pid=1433) INFO 12-10 22:51:40 [launcher.py:46] Route: /pooling, Methods: POST
(APIServer pid=1433) INFO: Started server process [1433]
(APIServer pid=1433) INFO: Waiting for application startup.
(APIServer pid=1433) INFO: Application startup complete.

3. 本地使用AutoGLM
3.1. 项目克隆
AutoGLM是一个定制的模型,必须要配合智谱开源的PhoneAgent SDK一起使用,需要本地有Python3.10+的环境

SH
1
2
3
4
5
6
# 克隆仓库
git clone https://github.com/zai-org/Open-AutoGLM.git
# 安装依赖
cd Open-AutoGLM
# 注意不要修改这个文件,只用安装里面给出的openai>=2.9.0和Pillow>=12.0.0
pip install -r requirements.txt
这里只是安装好了SDK的依赖,我们还需要给当前电脑配置ADB、链接手机到电脑上、给手机安装ADBKeyBoard等等操作。

考虑到AutoGLM模型面向的客户群体应该都会配置这些环境,本文就不多赘述了。如果你不太清楚咋配置ADB命令环境,请参考AutoGLM仓库的README,这里直接把README拷贝了过来:

安装ADB:

下载官方 ADB 安装包,并解压到自定义路径
配置环境变量:
MacOS 配置方法:在 Terminal 或者任何命令行工具里执行export PATH=${PATH}:~/Downloads/platform-tools,这里假设解压后的目录为 ~/Downlaods/platform-tools。如果不是请自行调整命令。
Windows 配置方法:可参考 第三方教程 进行配置。
安卓设备开启调试模式:

开发者模式启用:通常启用方法是,找到 设置-关于手机-版本号 然后连续快速点击 10
次左右,直到弹出弹窗显示“开发者模式已启用”。不同手机会有些许差别,如果找不到,可以上网搜索一下教程。
USB 调试启用:启用开发者模式之后,会出现 设置-开发者选项-USB 调试,勾选启用
部分机型在设置开发者选项以后, 可能需要重启设备才能生效. 可以测试一下: 将手机用USB数据线连接到电脑后, adb devices查看是否有设备信息, 如果没有说明连接失败。请务必仔细检查相关权限
安装 ADB Keyboard(用于文本输入,搞UI自动化基本都要装这个):

下载 安装包 并在对应的安卓设备中进行安装。
注意,安装完成后还需要到 设置-输入法 或者 设置-键盘列表 中启用 ADB Keyboard 才能生效
3.2. 运行Agent
安装完毕依赖之后,就可以直接运行了,把模型的base-url改成AutoDL上部署的外网url就可以了

SH
1
2
3
4
python main.py \
–base-url http://你的AutoDL服务地址:8443/v1 \
–model “autoglm-phone-9b” \
“帮我打开美团,买一杯瑞幸的椰香拿铁”
这里提醒一下,手机安装好ADBKeyBoard之后,必须要把手机默认输入法改成ADBKeyBoard,否则Agent在操作的时候还是会呼出给人用的输入法,导致没办法正常输入文字

main.py启动的时候,会对环境进行检查,模型url是否有效进行检查,检查通过了,就会开始任务(如下图所示),这时候你就可以看看你的手机,他是不是真运行起来啦!

 

注意,PhoneAgent是和AutoGLM绑定的,使用其他VL模型是没有用的!

4. The end
部署和使用到这里就结束啦!有什么问题欢迎评论区交流。

我现在就希望AutoGLM能有一个量化版本,能在Mac机器上用ollama之类的工具运行,这样就更好了。9b的模型理论上是可以被32GB内存的Mac加载运行的。不过我个人对大模型不太了解,不确定AutoGLM是否会强依赖Cuda环境,所以我的这个想法可能有失偏颇。

这里额外提一嘴:可能有朋友疑惑,为啥AutoGLM只支持安卓呢?

那是因为iOS的UI自动化,涉及到的Xcode配置、WDA配置、连手机、证书配置、开发者app认证那叫一个繁琐麻烦,不同iOS版本的很多系统级别弹窗样式都不一样,也得专门做适配。

总结来说:就是iOS的生态封闭,自动化配置麻烦。不同iOS系统版本之间变化大,为iOS做适配投入产出比不搞,纯纯是吃力不讨好。可不是安卓这边所有手机都内置的ADB那么方便的!

慕雪个人觉得,为鸿蒙做适配都比iOS容易!所有纯血鸿蒙的手机也都内置了hdc能力,本质上和安卓的adb是一套类似的工具!

脚注:
参考:https://github.com/zai-org/Open-AutoGLM/issues/5 ↩︎

作者: 慕雪年华
链接: https://blog.musnow.top/posts/3465160585/index.html
来源: 慕雪的寒舍
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

【零基础入门】Open-AutoGLM 完全指南:Mac 本地部署 AI 手机助理(原理+部署+优化)附上修改后代码-CSDN博客

mikel阅读(68)

来源: 【零基础入门】Open-AutoGLM 完全指南:Mac 本地部署 AI 手机助理(原理+部署+优化)附上修改后代码-CSDN博客

代码路径:
https://github.com/weidadedawei/Open-AutoGLM

目录
1. 什么是 Open-AutoGLM?
2. 核心原理解析
3. 环境准备(超详细)
4. 模型下载与部署
5. 实战操作指南
6. 性能优化详解
7. API 与进阶用法
8. 常见问题 FAQ
1. 什么是 Open-AutoGLM?
1.1 项目简介
Open-AutoGLM 是智谱 AI 开源的手机 AI 助理框架。它能让你的 Mac 变成一个”超级大脑”,通过 USB 或 WiFi 远程控制你的安卓手机,自动完成各种任务。

想象一下这些场景:

“帮我在饿了么点一份黄焖鸡米饭”
“打开微信给妈妈发消息说我今晚不回家吃饭”
“在网易云音乐搜索周杰伦的歌并播放”
“打开 B 站搜索 Python 教程”
这些以前需要你亲自动手的操作,现在只需一句话,AI 就能帮你完成!

1.2 为什么选择本地部署?
对比项 云端 API 模式 本地 MLX 模式
隐私安全 截图上传云端 数据永不出本机
运行成本 按 Token 收费 电费即成本
网络依赖 断网不可用 完全离线可用
响应延迟 网络延迟波动 本地计算稳定
1.3 适合谁?
开发者:想了解 AI Agent 如何工作
隐私敏感用户:不希望手机截图上传云端
极客玩家:想在本地玩转多模态大模型
学习者:想学习 MLX、ADB、多模态模型的实际应用
2. 核心原理解析
2.1 AI Agent 工作原理
Open-AutoGLM 采用经典的 感知-思考-行动 (Perception-Thinking-Action) 循环:

┌─────────────────────────────────────────────────────────────┐
│ Agent 工作循环 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 感 知 │ ──→ │ 思 考 │ ──→ │ 行 动 │ │
│ │ │ │ │ │ │ │
│ │ 截图 │ │ 理解状态 │ │ 点击 │ │
│ │ UI解析 │ │ 规划步骤 │ │ 滑动 │ │
│ │ App状态 │ │ 生成指令 │ │ 输入 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ ↑ │ │
│ └──────────────────────────────────┘ │
│ 循环执行 │
└─────────────────────────────────────────────────────────────┘
AI构建项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2.2 三层架构详解
感知层 (Perception Layer)

感知类型 技术实现 数据格式
视觉感知 adb shell screencap -p PNG 图像
结构化感知 adb shell uiautomator dump XML 元素树
状态感知 adb shell dumpsys activity App/Activity 信息
推理层 (Reasoning Layer)

AutoGLM-Phone-9B 是一个 视觉-语言模型 (VLM):

输入: [系统提示] + [任务描述] + [手机截图]

多模态编码器 (Vision Encoder)

Transformer 推理

输出: <think>推理过程</think><answer>{“action”: “Tap”, “element”: [500, 300]}</answer>
AI构建项目
1
2
3
4
5
6
7
模型会先在 <think> 标签中进行推理(类似 ChatGPT o1 的思考过程),然后在 <answer> 标签中输出具体的 JSON 操作指令。

执行层 (Execution Layer)

操作类型 ADB 命令 说明
Tap adb shell input tap x y 点击坐标
Swipe adb shell input swipe x1 y1 x2 y2 滑动
Type adb shell am broadcast -a ADB_INPUT_TEXT 输入文字
Launch adb shell am start -n package/activity 启动应用
2.3 MLX 框架介绍
MLX 是苹果公司专门为 Apple Silicon (M1/M2/M3/M4) 开发的深度学习框架:

统一内存架构:GPU 和 CPU 共享内存,无需复制数据
延迟编译:只编译实际执行的代码路径
原生 Metal 加速:充分利用 Apple GPU
对于本项目,MLX 让我们能在 Mac 上高效运行 9B 参数的多模态模型!

3. 环境准备(超详细)
3.1 系统要求
项目 最低要求 推荐配置
系统版本 macOS 13.3+ macOS 14+ (Sonoma)
芯片 M1 M1 Max / M2 Pro 及以上
内存 16GB (量化后) 32GB+
硬盘 20GB 可用空间 50GB+ SSD
Python 3.10+ 3.11
3.2 安装 Python 环境
方法 A:使用 Homebrew + pyenv(推荐)

# 1. 安装 Homebrew (如果没有)
/bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)”

# 2. 安装 pyenv
brew install pyenv

# 3. 配置 shell (以 zsh 为例)
echo ‘export PYENV_ROOT=”$HOME/.pyenv”‘ >> ~/.zshrc
echo ‘command -v pyenv >/dev/null || export PATH=”$PYENV_ROOT/bin:$PATH”‘ >> ~/.zshrc
echo ‘eval “$(pyenv init -)”‘ >> ~/.zshrc
source ~/.zshrc

# 4. 安装 Python 3.11
pyenv install 3.11.9
pyenv global 3.11.9

# 5. 验证安装
python –version # 应该显示 Python 3.11.9
AI构建项目
bash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
方法 B:使用 Conda

# 1. 下载 Miniforge (适合 Apple Silicon 的 Conda)
curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh

# 2. 安装
bash Miniforge3-MacOSX-arm64.sh

# 3. 创建虚拟环境
conda create -n autoglm python=3.11
conda activate autoglm
AI构建项目
bash
1
2
3
4
5
6
7
8
9
3.3 安装 ADB 工具
ADB (Android Debug Bridge) 是连接 Mac 和安卓手机的桥梁。

# 使用 Homebrew 安装
brew install Android-platform-tools

# 验证安装
adb version
AI构建项目
bash
1
2
3
4
5
3.4 配置安卓手机
步骤 1:开启开发者模式

打开 设置 → 关于手机
连续点击 版本号 7 次
看到提示”您已进入开发者模式”
不同品牌手机的位置可能略有不同。华为在”关于手机”,小米在”我的设备”。

步骤 2:开启 USB 调试

返回 设置 → 系统 → 开发者选项
开启 USB 调试
开启 USB 安装 (如果有)
关闭 监控 ADB 安装应用 (如果有)
部分手机需要重启后设置才能生效!

步骤 3:连接并授权

使用数据线(不是纯充电线!)连接手机和 Mac
手机上会弹出授权窗口,勾选”始终允许”并点击确定
在终端验证连接:
adb devices
# 输出应该类似:
# List of devices attached
# ABCD1234567890 device
AI构建项目
bash
1
2
3
4
3.5 安装 ADB Keyboard
ADB Keyboard 是一个特殊的输入法,允许通过 ADB 命令输入中文。

下载 APK:ADBKeyboard.apk

通过 ADB 安装:

adb install ADBKeyboard.apk
AI构建项目
bash
1
设置为当前输入法:

手机上进入 设置 → 语言和输入法 → 管理键盘
启用 ADB Keyboard
验证安装:

adb shell ime list -a | grep ADB
# 应该输出: com.Android.adbkeyboard/.AdbIME
AI构建项目
bash
1
2
3.6 安装项目依赖
# 1. 克隆项目
git clone https://github.com/zai-org/Open-AutoGLM.git
cd Open-AutoGLM

# 2. 安装 MLX 相关依赖
pip install mlx “git+https://github.com/Blaizzy/mlx-vlm.git@main” torch torchvision transformers

# 3. 安装项目依赖
pip install -r requirements.txt
pip install -e .

# 4. 验证安装
python -c “import mlx; import phone_agent; print(‘安装成功!’)”
AI构建项目
bash

1
2
3
4
5
6
7
8
9
10
11
12
13
4. 模型下载与部署
4.1 下载模型
方法 A:使用 HuggingFace CLI(推荐)

# 安装 CLI 工具
pip install -U “huggingface_hub[cli]”

# 设置国内镜像(可选,加速下载)
export HF_ENDPOINT=https://hf-mirror.com

# 下载模型(约 20GB)
huggingface-cli download –resume-download zai-org/AutoGLM-Phone-9B –local-dir ./models/AutoGLM-Phone-9B
AI构建项目
bash
1
2
3
4
5
6
7
8
方法 B:使用 ModelScope(国内最快)

pip install modelscope

python -c “from modelscope import snapshot_download; snapshot_download(‘ZhipuAI/AutoGLM-Phone-9B’, local_dir=’./models/AutoGLM-Phone-9B’)”
AI构建项目
bash
1
2
3
4.2 启动运行
下载完成后即可运行:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开微信”
AI构建项目
bash
1
4.3 可选:4-bit 量化(推荐 16GB 内存用户)
如果你的 Mac 内存只有 16GB,或希望更快的推理速度,可以对模型进行量化:

量化效果对比:

对比项 原始模型 (FP16) 4-bit 量化
模型大小 ~20GB ~6.5GB
内存占用 需 32GB+ 16GB 即可
推理速度 较慢 提升约 3x
精度损失 基准 约 1-2%
量化步骤:

# 执行量化转换(约 15-20 分钟)
python -m mlx_vlm.convert \
–hf-path ./models/AutoGLM-Phone-9B \
-q \
–q-bits 4 \
–mlx-path ./autoglm-9b-4bit
AI构建项目
bash
1
2
3
4
5
6
使用量化模型运行:

python main.py –local –model ./autoglm-9b-4bit “打开B站搜索二次元”
AI构建项目
bash
1
5. 实战操作指南
5.1 基础命令
交互模式:

python main.py –local –model ./models/AutoGLM-Phone-9B

# 然后输入任务:
> 打开微信
> 搜索张三并发送消息你好
> 退出
AI构建项目
bash
1
2
3
4
5
6
单任务模式:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开抖音刷5个视频”
AI构建项目
bash
1
5.2 常用参数
参数 说明 示例
–local 使用本地 MLX 推理 –local
–model 模型路径 –model ./models/AutoGLM-Phone-9B
–device-id 指定设备 –device-id 192.168.1.100:5555
–lang 语言 (cn/en) –lang en
–list-apps 列出支持的应用 –list-apps
–list-devices 列出连接的设备 –list-devices
5.3 任务示例
社交通讯:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开微信给张三发消息说:下午三点开会”
AI构建项目
bash
1
电商购物:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开淘宝搜索蓝牙耳机按价格排序”
AI构建项目
bash
1
美食外卖:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开美团外卖点一份黄焖鸡米饭”
AI构建项目
bash
1
视频娱乐:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开B站搜索Python教程”
AI构建项目
bash
1
音乐播放:

python main.py –local –model ./models/AutoGLM-Phone-9B “打开网易云音乐搜索周杰伦的晴天并播放”
AI构建项目
bash
1
5.4 WiFi 远程调试
无需 USB 线也能控制手机!

步骤 1:开启无线调试

确保手机和 Mac 在同一 WiFi 下
进入 开发者选项 → 无线调试
开启无线调试,记下 IP 和端口
步骤 2:连接设备

# 连接远程设备
adb connect 192.168.1.100:5555

# 验证连接
adb devices

# 使用远程设备执行任务
python main.py –local –model ./models/AutoGLM-Phone-9B \
–device-id 192.168.1.100:5555 \
“打开抖音刷视频”
AI构建项目
bash

1
2
3
4
5
6
7
8
9
10
5.5 支持的操作类型
操作 说明
Tap 点击指定坐标
Swipe 滑动屏幕
Type 输入文本
Launch 启动应用
Back 返回上一页
Home 返回桌面
Long Press 长按
Double Tap 双击
Wait 等待页面加载
Take_over 请求人工接管
6. 性能优化详解
6.1 内置优化(自动生效)
我们在代码中实现了三项关键优化:

优化 1:智能图像降采样

现代手机屏幕动辄 2K/4K,直接处理太慢。系统自动将图像长边限制在 1024 像素以内。

原始尺寸 处理后尺寸 像素减少
2400×1080 1024×460 82%
1920×1080 1024×576 72%
优化 2:KV Cache 量化

推理时启用 kv_bits=8,将 KV Cache 从 FP16 量化到 INT8:

显存占用降低约 30%
推理速度略有提升
优化 3:显存强制回收

每步推理后强制执行 mx.clear_cache() 和 gc.collect():

防止”越用越卡”
长时间运行保持稳定
6.2 手动优化建议
关闭不必要的后台应用:MLX 推理需要大量内存
使用有线连接:USB 比 WiFi 更稳定,截图传输更快
降低手机亮度:高亮度截图文件更大
定期重启模型:如果变慢了,Ctrl+C 终止后重新启动
6.3 性能参考
在 Mac Studio M1 Max (32GB) 上使用 4-bit 量化模型:

阶段 耗时
模型加载 约 30 秒
单步推理 13-18 秒
截图获取 0.5-1 秒
完整任务示例:“打开网易云音乐搜索歌曲一滴泪的时间播放”

总步数:6 步
总耗时:约 2 分 18 秒
7. API 与进阶用法
7.1 Python API 调用
from phone_agent import PhoneAgent
from phone_agent.model import ModelConfig
from phone_agent.agent import AgentConfig

# 配置模型
model_config = ModelConfig(
model_name=”./models/AutoGLM-Phone-9B”,
is_local=True,
max_tokens=3000,
temperature=0.1,
)

# 配置 Agent
agent_config = AgentConfig(
max_steps=50,
verbose=True,
lang=”cn”,
)

# 创建并运行
agent = PhoneAgent(
model_config=model_config,
agent_config=agent_config,
)

result = agent.run(“打开抖音刷3个视频”)
print(f”任务结果: {result}”)
AI构建项目
python
运行

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
7.2 自定义回调函数
处理敏感操作和人工接管场景:

def my_confirmation(message: str) -> bool:
“””敏感操作确认(如支付)”””
print(f”检测到敏感操作: {message}”)
return input(“是否继续?(y/n): “).lower() == “y”

def my_takeover(message: str) -> None:
“””人工接管(如登录验证)”””
print(f”需要人工操作: {message}”)
input(“完成后按回车继续…”)

agent = PhoneAgent(
confirmation_callback=my_confirmation,
takeover_callback=my_takeover,
)
AI构建项目
python
运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
7.3 批量执行任务
tasks = [
“打开微信给张三发消息:会议改到下午4点”,
“打开支付宝查看余额”,
“打开美团查看最近订单”,
]

for task in tasks:
result = agent.run(task)
print(f”完成: {task}”)
agent.reset()
AI构建项目
python
运行

1
2
3
4
5
6
7
8
9
10
7.4 配置参数参考
ModelConfig 参数:

参数 类型 默认值 说明
model_name str – 模型路径
is_local bool False 使用本地推理
max_tokens int 3000 最大输出 token
temperature float 0.1 采样温度
AgentConfig 参数:

参数 类型 默认值 说明
max_steps int 100 最大执行步数
device_id str None ADB 设备 ID
lang str cn 语言
verbose bool True 显示详细输出
8. 常见问题 FAQ
Q1: 设备未找到
adb devices # 输出为空
AI构建项目
bash
1
解决方案:

adb kill-server
adb start-server
adb devices
AI构建项目
bash
1
2
3
常见原因:

数据线是纯充电线
没有在手机上授权
开发者选项未正确开启
Q2: 模型加载失败 / 下载中断
# 使用断点续传
huggingface-cli download –resume-download zai-org/AutoGLM-Phone-9B –local-dir ./models/AutoGLM-Phone-9B

# 或使用国内镜像
export HF_ENDPOINT=https://hf-mirror.com
AI构建项目
bash
1
2
3
4
5
Q3: 内存不足 (Killed / MemoryError)
使用 4-bit 量化版本(见 4.3 节)
关闭其他应用
重启 Mac 后再试
Q4: 文本输入不工作
确认已安装 ADB Keyboard
确认已在系统中启用
验证安装:
adb shell ime list -a | grep ADB
AI构建项目
bash
1
Q5: 截图失败 (黑屏)
这是系统安全机制,某些应用(支付、银行)禁止截图。模型会自动请求人工接管。

Q6: 运行变慢 / 卡顿
# 终止并重新启动
Ctrl+C
python main.py –local –model ./models/AutoGLM-Phone-9B “你的任务”
AI构建项目
bash
1
2
3
Q7: WiFi 连接失败
确保手机和电脑在同一 WiFi
确保手机开启了无线调试
检查防火墙是否阻止 5555 端口
Q8: Windows/Linux 编码问题
# Windows
set PYTHONIOENCODING=utf-8

# Linux
export PYTHONIOENCODING=utf-8
AI构建项目
bash
1
2
3
4
5

————————————————
版权声明:本文为CSDN博主「伟大的大威」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010026928/article/details/155782313

ADBKeyBoard 安装 (中文输入)-CSDN博客

mikel阅读(106)

来源: ADBKeyBoard 安装 (中文输入)-CSDN博客

问题:

adb shell input text ‘你好嗎’
is not going to work.
AI构建项目
bash

ADBKeyboard 在这些情况下会有所帮助,尤其是在设备自动化和测试中

1. 下载
github网址:https://github.com/senzhk/ADBKeyBoard?tab=readme-ov-file
apk下载:
https://github.com/senzhk/ADBKeyBoard/blob/master/ADBKeyboard.apk
将下载好的apk放置在cmd命令同一个文件夹中,同时手机开启权限,可通过adb安装应用

 

2. 安装
安装命令:

adb install ADBKeyboard.apk
AI构建项目
bash

设置手机输入法

adb shell ime enable com.Android.adbkeyboard/.AdbIME
adb shell ime set com.Android.adbkeyboard/.AdbIME
AI构建项目
bash
示例
使用案例

import os
import base64

chars = “你好”
charsb64 = str(base64.b64encode(chars.encode(“utf-8”)))[1:]
os.system(“adb shell am broadcast -a ADB_INPUT_B64 –es msg %s” % charsb64)
AI构建项目
python
运行

测试完成,返回原先的输入法:
原先输入法为:com.baidu.input_mi/.ImeService

adb shell ime set com.baidu.input_mi/.ImeService
AI构建项目
bash

其他命令

adb shell ime list -a # Check your available virtual keyboards
adb shell ime reset # Reset to default, don’t care which keyboard was chosen before switch
————————————————
版权声明:本文为CSDN博主「ZHOU_CAMP」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41472205/article/details/144773591