2025-07-20 13:27:27
在几个月前,我购买了一个 8845HS 的主机,尝试了一番 ROCm,AMD 在 API 的 iGPU 支持上可以说相当慢了,直到目前也只是在利用 DirectML 和 ONNX 的能力实现 iGPU 上运行模型,非常费劲。
Intel 这边就优雅且慷慨的多,oneAPI 统一了 CPU GPU NPU 多端的运行,看起来非常的靠谱,并且提供了 PyTorch+XPU 的后端,已经并入官方仓库,意味着 PyTorch 项目只需要简单的修改下模型的 device 就可以推理了,真是一种方便你我他的好方案。
PyTorch+XPU 安装起来也非常简单,通过这个命令即可:
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/xpu
这个官方编译的 XPU 版本集成了 https://github.com/intel/torch-xpu-ops 的算子支持
不过有了上次 8845HS 的经验后,我也没有贸然下单,总想着先找个机器测一测吧,几经辗转,发现 Intel 的 Tiber Cloud 已经可以用了,开了台机器简单测了几个场景,相较 ROCm 之前在 iGPU 的各种报错,Intel 的 XPU 后端顺利的过于幸福。
Tiber 虽然提供的是 Intel 的商用 GPU,但既然官方表示是一视同仁,我相信 iGPU 的支持也不会差,立刻购入了一个摸到支持门坎的 Ultra 5 225H 的迷你主机,瞧瞧是什么情况。
先测一下 Kokoro 这个 TTS 模型
from kokoro import KPipeline
from IPython.display import display, Audio
import soundfile as sf
pipeline = KPipeline(lang_code='a', device='xpu')
text = '''
[Kokoro](/kˈOkəɹO/) is an open-weight TTS model with 82 million parameters. Despite its lightweight architecture, it delivers comparable quality to larger models while being significantly faster and more cost-efficient. With Apache-licensed weights, [Kokoro](/kˈOkəɹO/) can be deployed anywhere from production environments to personal projects.
'''
generator = pipeline(text, voice='af_heart')
for i, (gs, ps, audio) in enumerate(generator):
print(i, gs, ps)
display(Audio(data=audio, rate=24000, autoplay=i==0))
sf.write(f'{i}.wav', audio, 24000)
这个 20s 的音频首次生成大概是 4s,之后大概花费 2s 左右
import soundfile as sf
from misaki import en, espeak
from kokoro_onnx import Kokoro
# Misaki G2P with espeak-ng fallback
fallback = espeak.EspeakFallback(british=False)
g2p = en.G2P(trf=False, british=False, fallback=fallback)
# Kokoro
kokoro = Kokoro("kokoro-v1.0.onnx", "voices-v1.0.bin")
# Phonemize
text = '''
[Kokoro](/kˈOkəɹO/) is an open-weight TTS model with 82 million parameters. Despite its lightweight architecture, it delivers comparable quality to larger models while being significantly faster and more cost-efficient. With Apache-licensed weights, [Kokoro](/kˈOkəɹO/) can be deployed anywhere from production environments to personal projects.
'''
phonemes, _ = g2p(text)
# Create
samples, sample_rate = kokoro.create(phonemes, "af_heart", is_phonemes=True)
# Save
sf.write("audio.wav", samples, sample_rate)
print("Created audio.wav")
Intel 可以通过 pip install onnxruntime-openvino
来开启 GPU 的支持,稍微修改下 Kokoro 这个类
providers = [('OpenVINOExecutionProvider', {'device_type': 'GPU'})]
很遗憾,出错了
RuntimeException: [ONNXRuntimeError] : 6 : RUNTIME_EXCEPTION : Exception during initialization: /onnxruntime/onnxruntime/core/providers/openvino/ov_interface.cc:98 onnxruntime::openvino_ep::OVExeNetwork onnxruntime::openvino_ep::OVCore::CompileModel(std::shared_ptr<const ov::Model>&, std::string&, ov::AnyMap&, const std::string&) [OpenVINO-EP] Exception while Loading Network for graph: OpenVINOExecutionProvider_OpenVINO-EP-subgraph_1_0Exception from src/inference/src/cpp/core.cpp:109:
Exception from src/inference/src/dev/plugin.cpp:53:
Check 'inputRank == 2 || inputRank == 4 || inputRank == 5' failed at src/plugins/intel_gpu/src/plugin/ops/interpolate.cpp:37:
Mode 'linear_onnx' supports only 2D or 4D, 5D tensors
PaddleOCR-onnx 需要修改一下 PredictBase 这个类
if use_gpu:
providers = [('OpenVINOExecutionProvider', {
'device_type': 'GPU'})]
也可以使用 'device_type': 'NPU' 'device_type': 'HETERO:GPU,CPU' 这类方式指定计算方式
然后运行项目自带的 test_ocr.py 即可,开启 use_gpu=True
import cv2
import time
from onnxocr.onnx_paddleocr import ONNXPaddleOcr, sav2Img
import sys
import time
model = ONNXPaddleOcr(use_angle_cls=False, use_gpu=True)
img = cv2.imread('./onnxocr/test_images/00006737.jpg')
s = time.time()
result = model.ocr(img)
e = time.time()
for box in result[0]:
print(box)
print("total time: {:.3f}".format(e - s))
sav2Img(img, result, name=str(time.time())+'.jpg')
运行良好,花费了大概 1s
Ollama 的 Intel 支持需要通过 https://github.com/intel/ipex-llm 这个项目,使用 Intel 编译的 Ollama 在运行时可以看到
get_memory_info: [warning] ext_intel_free_memory is not supported (export/set ZES_ENABLE_SYSMAN=1 to support), use total memory as free memory
get_memory_info: [warning] ext_intel_free_memory is not supported (export/set ZES_ENABLE_SYSMAN=1 to support), use total memory as free memory
看来自己不需要解决 iGPU 有多少显存的问题
比 8845HS 的 8 tokens/s 慢一些,不知道未来 ipex-llm 是不是还能在这里加把劲。
这次玩下来,PyTorch 的支持挺不错,足以作为一个推理机器使用。
SD 有两个选择,一个是 Diffusers,一个则是 stable-diffusion.cpp
Flux 占用的内存真的不少,32GB 内存跑 FP16 完全不够,官方也给出了的例子使用 GGUF 量化模型的方法,不过这个方案还是不够省内存
import torch
from diffusers import FluxPipeline, FluxTransformer2DModel, GGUFQuantizationConfig
ckpt_path = (
"./models/flux1-dev-Q4_0.gguf"
)
transformer = FluxTransformer2DModel.from_single_file(
ckpt_path,
quantization_config=GGUFQuantizationConfig(compute_dtype=torch.bfloat16),
torch_dtype=torch.bfloat16,
)
pipe = FluxPipeline.from_pretrained(
"black-forest-labs/FLUX.1-dev",
transformer=transformer,
torch_dtype=torch.bfloat16
)
pipe.enable_model_cpu_offload()
prompt = "A cat holding a sign that says hello world"
image = pipe(prompt,
generator=torch.manual_seed(0),
num_inference_steps=20,
height=512,
width=512
).images[0]
image.save("flux-gguf.png")
这部分我参考了此处的实现 ,通过分步的方式节省了不少内存
import torch
from diffusers import FluxPipeline, FluxTransformer2DModel, GGUFQuantizationConfig
import gc
def flush():
gc.collect()
torch.xpu.empty_cache()
def main():
# downloaded from https://huggingface.co/city96/FLUX.1-dev-gguf
gguf_file = "./models/flux1-dev-Q4_K_S.gguf"
model_id = "black-forest-labs/FLUX.1-dev"
pipeline = FluxPipeline.from_pretrained(
model_id,
transformer=None,
vae=None,
torch_dtype=torch.bfloat16
).to("xpu")
prompt = "a lovely cat holding a sign says 'hello world'"
with torch.no_grad():
prompt_embeds, pooled_prompt_embeds, text_ids = pipeline.encode_prompt(
prompt=prompt,
prompt_2=None,
)
print("text_encoder:")
print(f"torch.xpu.max_memory_allocated: {torch.xpu.max_memory_allocated()/ 1024**3:.2f} GB")
del pipeline
flush()
transformer = FluxTransformer2DModel.from_single_file(
gguf_file,
quantization_config=GGUFQuantizationConfig(compute_dtype=torch.bfloat16),
torch_dtype=torch.bfloat16
)
pipeline = FluxPipeline.from_pretrained(
model_id,
transformer=transformer,
text_encoder=None,
text_encoder_2=None,
tokenizer=None,
tokenizer_2=None,
torch_dtype=torch.bfloat16
).to("xpu")
image = pipeline(
prompt_embeds=prompt_embeds,
pooled_prompt_embeds=pooled_prompt_embeds,
generator=torch.Generator("xpu").manual_seed(0),
height=512,
width=512,
num_inference_steps=20
).images[0]
save_file = gguf_file.replace(".gguf", ".jpg")
image.save(save_file)
print("transformer:")
print(f"torch.xpu.max_memory_allocated: {torch.xpu.max_memory_allocated()/ 1024**3:.2f} GB")
if __name__ == "__main__":
main()
Q4 结果如下
Loading checkpoint shards: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 94.74it/s]
Loading pipeline components...: 60%|████████████████████████████████████████████████████████▍ | 3/5 [00:00<00:00, 28.63it/s]You set `add_prefix_space`. The tokenizer needs to be converted from the slow tokenizers
Loading pipeline components...: 100%|██████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 14.99it/s]
text_encoder:
torch.xpu.max_memory_allocated: 9.32 GB
Loading pipeline components...: 100%|██████████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:00<00:00, 48.13it/s]
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 20/20 [02:52<00:00, 8.62s/it]
transformer:
torch.xpu.max_memory_allocated: 9.32 GB
Q8 结果如下
Loading checkpoint shards: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 19.84it/s]
Loading pipeline components...: 100%|██████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 11.03it/s]
text_encoder:
torch.xpu.max_memory_allocated: 9.32 GB
Loading pipeline components...: 100%|██████████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:00<00:00, 45.77it/s]
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 20/20 [01:41<00:00, 5.06s/it]
transformer:
torch.xpu.max_memory_allocated: 12.61 GB
Q8 比 Q4 更快,神奇,似乎是因为硬件有原生 Q8 的加速支持
stable-diffusion.cpp 除了对后端支持很全面( CUDA, Metal, Vulkan, OpenCL and SYCL)另一大优点应该就是占内存比较少了,结合其 Python 的绑定 stable-diffusion-cpp-python可以轻松跑起来 Q8 的模型
from stable_diffusion_cpp import StableDiffusion
import torch
def callback(step: int, steps: int, time: float):
print("Completed step: {} of {}".format(step, steps))
gen = torch.Generator(device="xpu").manual_seed(0)
stable_diffusion = StableDiffusion(
diffusion_model_path="./models/flux1-dev-Q8_0.gguf", # In place of model_path
clip_l_path="./models/clip_l.safetensors",
t5xxl_path="./models/t5xxl_fp16.safetensors",
vae_path="./models/ae.safetensors",
vae_decode_only=True, # Can be True if we dont use img_to_img
)
output = stable_diffusion.txt_to_img(
prompt="a lovely cat holding a sign says 'hello world'",
sample_steps=20,
width=512, # Must be a multiple of 64
height=512, # Must be a multiple of 64
cfg_scale=1.0, # a cfg_scale of 1 is recommended for FLUX
sample_method="euler", # euler is recommended for FLUX
progress_callback=callback,
seed=gen.initial_seed()
)
output[0].save("output.png")
Q4 结果如下
stable-diffusion.cpp:1525 - sampling completed, taking 113.58s
stable-diffusion.cpp:1533 - generating 1 latent images completed, taking 113.58s
stable-diffusion.cpp:1536 - decoding 1 latents
ggml_extend.hpp:1148 - vae compute buffer size: 1664.00 MB(VRAM)
stable-diffusion.cpp:1129 - computing vae [mode: DECODE] graph completed, taking 11.54s
stable-diffusion.cpp:1546 - latent 1 decoded, taking 11.54s
stable-diffusion.cpp:1550 - decode_first_stage completed, taking 11.54s
stable-diffusion.cpp:1684 - txt2img completed in 138.73s
Q8 结果如下
stable-diffusion.cpp:1525 - sampling completed, taking 117.70s
stable-diffusion.cpp:1533 - generating 1 latent images completed, taking 117.70s
stable-diffusion.cpp:1536 - decoding 1 latents
ggml_extend.hpp:1148 - vae compute buffer size: 1664.00 MB(VRAM)
stable-diffusion.cpp:1129 - computing vae [mode: DECODE] graph completed, taking 11.57s
stable-diffusion.cpp:1546 - latent 1 decoded, taking 11.57s
stable-diffusion.cpp:1550 - decode_first_stage completed, taking 11.57s
stable-diffusion.cpp:1684 - txt2img completed in 144.15s
可以使用 Intel 提供的性能查看工具 intel_gpu_top
也可以使用 watch -n 1 xpu-smi stats -d 0
2025-03-24 13:11:58
最近买了个 8845HS 的小主机,但因为 780m 的显卡并没有被 ROCm 列为官方支持的卡,所以目前需要很多 trick 来运行
最主要的就是通过 HSA_OVERRIDE_GFX_VERSION
来假装成受支持的显卡。虽然我用的都是 HSA_OVERRIDE_GFX_VERSION=11.0.2 但实际上因 ROCm 版本的不同,到底哪个能在你的显卡上工作需要自己测试下。
你可以通过 AMD 官网的 Supported GPUs 中的 Architecture 和 LLVM target 来查找,比如 gfx1101,那就是 HSA_OVERRIDE_GFX_VERSION=11.0.1
除此之外,ls /opt/rocm/lib/rocblas/library
命令也会列出一些没显示在官网上的支持,比如 11.0.2
ROCm 是 AMD 显卡玩机器学习的基础组件,现在安装起来很简单,amdgpu-install 这个包就可以很好的解决
sudo apt install amdgpu-install
amdgpu-install --usecase=rocm
Ollama 的运行可以参考下面的 PR Enable AMD iGPU 780M in Linux, Create amd-igpu-780m.md #5426
简而言之,直接通过这个命令就可以运行
HSA_OVERRIDE_GFX_VERSION=11.0.2 ollama serve
目前 Ollama 对 igpu 的显存支持有些问题,不能够将所有共享内存计算在内,解决方案可以参考这里 AMD integrated graphic on linux kernel 6.9.9+, GTT memory, loading freeze fix #6282
我的主要场景并非用 8845HS 来跑 LLM,所以就跑个简单的测试下吧,gemma3:12b 这个量化模型的速度大概是 8.44 tokens/s 可以说堪用
使用 ollama ps
命令可以查看模型是分配在哪个设备上运行的。
PyTorch 直接通过AMD 官网提供的命令来安装即可,需要注意的是我使用 PyTorch 官网的命令安装稳定版并不能成功运行,AMD 官网给出的 nightly 版本可以。
pip3 install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/rocm6.2.4/
同样,需要使用 HSA_OVERRIDE_GFX_VERSION=11.0.2
来运行,可以创建一个 .env 文件在 ipynb 里动态载入,如果是 vscode 的话,.env 文件会自动加载,不需要下述步骤
pip install python-dotenv
在 ipynb 顶部加入一个 code block 每次运行一下即可
%load_ext dotenv
%dotenv
其它内容无需修改
配置完成后,如果有时候不确定有没有跑在 GPU 上,可以用 radeontop 来监控
sudo apt install radeontop
8845HS 还带了个 16 TOPS 的 NPU,不过要等到 Linux 6.14 才会合并进去。
届时 ONNX Runtime 的 VitisAIExecutionProvider 和 HuggingFace 的 RyzenAI 应该都能开箱即用。
唯一的问题是兼容性如何。
暂时还没折腾,等到时候也会测试一下再写一篇折腾的博客
Does ROCm 5.7 support Radeon 780M (gfx1103)? #2631
Feature: ROCm Support for AMD Ryzen 9 7940HS with Radeon 780M Graphics #3398
2025-03-20 16:25:56
最近经常想起自己为什么离开公司自己做产品,都已经是 7 年前的事情了
当时为了能够按照自己的意志去做产品
做一款足够独特,有趣的产品
这些年事情虽然做的慢了些
但现在对这个目标有了更好的想法,更成熟的思考
7 年间发生了很多事情,失去了挚友
身份,家庭,关系也都在变化
但今天我真的迈入新的副本了
副本开始前,是应该好好休息一下的!
2025-03-08 11:07:40
昨天看介绍说乔布斯在设计苹果的新总部时希望有在公园里办公的感觉,因为在亲近自然的时候最有灵感。
想起了去年住的东越谷,东越谷是真的挺美的,河道,公园,家里的窗外。
因为不能养猫所以搬家了,离开了这个环境后经常会想念,所以也在考虑是不是应该再搬家,找一个能养猫又亲近自然的地方。
但还是等春天来了之后,看看这里万物复苏后是什么感觉,或许也会很美。
最近集中看了一些电影,「怪物」「去唱卡拉OK吧」「爱的接力棒」这些
感觉也许是自己真的步入中年,远离青春了
「去唱卡拉OK吧」是那种后劲很足的青春感
而且不是那种恋爱的青春
2024-12-07 18:40:02
11 月中旬的时候,Andy 私信问我愿不愿意体验一下懒猫微服这款产品,我看了下懒猫微服的官网,然后几个疑问就冒了出来
于是我对 Andy 说,关注我的人应该大都懂技术,对参数也比较敏感,可能找一些数码博主来体验会更好。
但 Andy 还是说,你先体验下,如果喜欢的话就点评点评。
好吧,既然条件这么宽松,我也很好奇原 Deepin Linux CTO 带来的产品,会有什么不同,在这些问题中,我最好奇的是懒猫的网络穿透技术,是不是真的能构建出有用的使用场景。
因此本次的体验将跳过所有和外观以及参数相关的内容,只在于使用场景的探索。
懒猫到手后配置的流程很简单,打开 App 扫机器底部的二维码,几个下一步就可以配置好,和 HomeKit 的智能设备入网差不多。这个流畅简单的体验是让我觉得有些惊喜的,和我之前用的 NAS 相比是非常新手友好了。
与传统 NAS 不同的是,你暂时无法直接通过一个局域网的地址访问懒猫微服,想要正常使用懒猫,都需要启动他们的 App 进行组网,然后通过 App 管理和访问懒猫的功能。
比较省心的是,不论你身处何地,都可以通过这个懒猫微服的内网穿透能力,无缝的访问家里懒猫微服的应用和内容。
原理上来说,懒猫微服会通过内网穿透组网的能力,将你登陆了懒猫 App 的设备和你家里的懒猫微服组合到一个加密的私有网络里,在这之后,懒猫 App 会接管你设备上所有访问 heiyu.space 域名后缀的流量,而每个你安装的懒猫上的应用,都会有对应的 heiyu.space 域名,比如懒猫清单对应的就是 https://todolist.myoland.heiyu.space
当你访问这个域名的时候,无需经过第三方中转即可直连家中的懒猫微服,这意味着你既不需要租服务器,处理那些烦人的备案合规问题,也不需要担心带宽和流量问题,更无须担心自己的数据会被窥窃。
如果这个域名只有自己能访问,那就相当无趣了,懒猫让我开始觉得兴奋的地方是,你可以邀请最多 20 名用户加入到你的微服上,这意味着,虽然他们没有微服设备,但可以访问,操控,管理你的懒猫微服和上面的应用。
在看到懒猫这种便利的组网能力后,我立刻想起了我之前和团队成员协作时一直在用的 Mattermost,一个 Slack 的开源替代品,出于数据安全的考虑,我并不想使用国内的协作产品聊天,但我又需要大家能稳定的连接到这个服务上,一个架设在自己家里的 Mattermost 就是很好的选择。
可惜在我使用的时候懒猫微服的应用商店还没有上架这个应用。
好吧,自己动手丰衣足食,这也是增进对懒猫了解的好机会,我着手移植了一个懒猫微服版本的 Mattermost,在这篇 Blog 发布的日期,我已经提交 Mattermost 到懒猫的应用商店,如果你想参考移植自己的项目,可以在这里找到项目代码 https://github.com/kevinzhow/mattermost-lzc
Mattermost 在安装后你可以访问 https://mattermost.myoland.heiyu.space 来打开 Mattermost,也可以直接通过这个域名在 App 上登录。
得益于懒猫 App 在电脑端不错的兼容性,懒猫微服不会和你电脑上其他的 VPN 服务冲突,Mattermost 用起来也非常无缝,在一些网络配置后,远程协助和电话功能也都能正常运行,这一刻我有些爱上了懒猫微服为团队协作提供的便利性。
团队协作第二个最常见的需求就是点对点文件同步,以前一直用 Resilio 进行同步,但是感觉不论是权限管理还是后来的改动,都让我用的有些不开心,这次我尝试了 Syncthing 这款开源产品。
虽然懒猫的应用商店自带了 Syncthing 但是有两个问题导致我还是自己进行了一次移植
你可以在这里找到我的移植项目 https://github.com/kevinzhow/syncthing-lzc
因为一开始我带入了 NAS 的概念,所以看到硬盘 1 和 硬盘 2 的使用量一样时,我以为是组了 RAID,但客服告诉我这是 btrfs 均匀存储的特性,多年 Mac 用户此刻表示受到了开源震撼。
我另外一台 NAS 虽然用了 RAID 技术,但比起 RAID 让人摸不清头脑的规格,我个人更喜欢懒猫这种外接一个 USB 硬盘进行增量数据备份的方式,机器因此可以做小,更省电,自己也可以更自由的管理移动备份硬盘。
其实在找到了团队协作这个场景之后,我认为懒猫微服已经给我提供了一个非常独特的使用场景,从一开始带着偏见的怀疑,变成了希望他们做大做强。
正如它名字里体现的一样,这是一个开箱即用的私有云服务主机,NAS 和 AI 都不是它打动我标签,懒猫微服隐藏了 NAS 产品过去的复杂细节,将微服这个概念交付到了用户手中。
希望不折腾,拥有开箱即用的私有云服务主机的人。 另外懒猫很快会推出海外版本,相信届时如果结合 Cloudflare Tunnel,这应该也会是一个非常好的公网服务器。
2024-10-10 18:47:53
这次搬家是彻底失算了,没想到日本 2022 年的新筑 Terrace (日语叫 メゾンネット,中文可以理解为联排)竟然没有光纤,这就导致在各家装宽带的网页上,公寓和一户建都不太能准确描述这个地方。
各种波折导致我没能顺利搬迁之前的宽带,也没能很快装上新的宽带。这也是为什么我会写这篇文章,主要是抒发下没有宽带的苦闷。
日本很多运营商都提供了一种叫做 Home Wi-Fi 的家庭热点,原理和手机热点一样,都是通过一张 SIM 卡连接到移动网络,然后再分享出来。
但与手机不同的是,Home WI-FI 这种设备把技能点都点在了下载上。
比如在我这里通过 5G 连接 Au 的线路,下载可以到 200M,但上传可能只有 10M - 20M,同样的卡切换成我的 Pixel 7a 之后,下载是 120M 左右,上传是 60 - 80M. 下图可以看到 Pixel 7a 的上传性能要好很多。
有了这个数据的对比后,我决定把 Android 手机的网通过 RJ45 网线提供给路由器上网。
在日本 Android 手机只能分享 2.4G 的 WI-FI,这导致 WI-FI 的速度和稳定性,带机量都相当有限。
具备下面 3 个物品就可以方便的自制一个 Home WI-FI 了
在日本的话 Povo 和乐天这两个放题卡都是不错的选择,需要注意的是自己所在的区域是否有对应的 5G 信号支持,5G 通常可以提供一个 20ms 左右的低延迟体验,即使人多的时候速度不会降的离谱。
虽然 小米,三星,Google Pixel 的手机大都支持以太网网络共享,但这一点还是需要自己先确认下。
你可以选择一个带有 Type C 供电的转接头,比如我购买的支持 PD 电源输入的这款
除了专门买个转接头外,也可以用自己手头带有 RJ45 接口的扩展坞,但扩展坞和手机的兼容性可能不太好,比如我手里的 Anker 扩展坞可以和小米手机一起用,但 Pixel 使用则会一直掉线。
在购买前需要确认转接设备和 Android 手机的兼容性,一般如果商家写了支持 Android 设备那么通常没问题。
正常的家用 WI-FI 路由器即可 :)
好了,可以享受网络了!我用了一个星期后感觉还是挺稳定的,不过还是祝你早日装上宽带!