有没有人知道 kimi 199 套餐 api 能不能使用多模态的图片识别
不知有没有大佬知道这个
xiaohack博客专注前沿科技动态与实用技术干货分享,涵盖 AI 代理、大模型应用、编程工具、文档解析、SEO 实战、自动化部署等内容,提供开源项目教程、科技资讯日报、工具使用指南,助力开发者、AI 爱好者获取前沿技术与实战经验。

我已经买了。不需要再买了。
之前我都是在江浙沪的,一直都是押一付三或者押一付一的,为什么这里很多都要押一付二

前段时间由于刚开通汇丰账户不久,不太清楚汇丰银行的规则,在操作过程中触发了风控导致账户被锁。虽然过程比较波折,但最终成功解封。
为了避免大家重蹈覆辙,我花时间复盘了这次从“账户被锁”到“成功解封”的全过程。如果你在使用汇丰( HSBC )账户时遇到了 SAS301 报错,这篇笔记应该能帮你节省几天的时间。
核心教训:新账户磨合期不要随意点击未开通的理财功能,资金不要大笔汇入快进快出,而且如果有香港电话必检查手机拦截设置。
如果有想开通香港账户的朋友,可以参考:肉身实测:香港一日极限开 4 张卡(汇丰/ZA/天星/中银)全流程复盘与避坑指南

复盘整个过程,这次风控并非因为资金问题,而是因为操作行为被系统判定为异常。
1. 账户背景 账户刚开通不到半个月。在此期间,我向账户内转了三笔资金,全部为同名账户互转,资金链路非常干净,没有任何问题。
2. 触发操作(关键点) 出于好奇,我在 APP 内点击了 “理财账户” 功能。 由于该功能需要实时拍摄身份证进行验证,而当时我并未随身携带证件,因此我中途直接关闭了两次开通流程,只简单浏览了一下股票界面。
3. 爆发节点 第二天尝试进行转账交易时,系统直接拦截,弹出 “SAS301” 报错代码,显示无法转账。至此,账户资金被实质性冻结。
推测结论:汇丰的风控机制非常敏感。在新号磨合期,连续发起“开通投资账户”请求又中途放弃,极大概率被系统判定为风险操作或非本人操作。
发现报错后,我经历了线上咨询和电话沟通两个环节。这里有一个巨大的坑,导致我白白浪费了两天时间。
1. 线上咨询 第一时间联系了 APP 内的线上客服。对方询问了交易详情和时间,但最终回复:线上客服无权解封,必须通过电话处理,并提供了一个联系号码。


2. 电话沟通(踩坑经历) 拨打客服电话后,工作人员记录了我的情况,表示会有专员进行核实,让我留意接听回电。
3. 严重避坑:国内手机的默认设置 在这里我吃了一个大亏。在等待回电的两天里,我一直没有接到任何电话。后来检查才发现:
问题所在:国内运营商或手机系统默认开启了 “拦截海外/境外来电” 的功能(海外接听电话还是蛮贵的,我显示的是 0.84/每分钟,而且接听也需要收费,如果有香港的手机号码注册的时候建议使用香港的手机号码,因为注册的时候填写的是大陆的+86 手机号码,如果你的是香港的手机号码就这个问题。)
后果:银行的核实电话被系统自动拦截,导致我错过了审核时效,耽误了两天。

还有一个点就是给我接待的那个经理只有工作日上班,在周末的时间是不上班的,这也导致我只非工作日时间没有办法完成账户认证。
4. 最终解封 解决拦截问题后,我终于接到了工作人员的电话。流程非常简单:
对方询问了基本情况。
核实身份信息。
当场解除账户封锁,账户恢复正常使用。
确认当天我就尝试了转账,成功转账
经过这次折腾,总结出以下三条规则都是我自己踩得坑,希望给刚开好汇丰卡的朋友有参考意义:
1. 磨合期少操作生僻功能 在账户刚开通的“磨合期”(通常为前 1-3 个月),尽量只进行基础的存取款操作。不要出于好奇去点击借贷、理财、投资等不常用的功能,尤其是不要在流程中反复进入和退出,这极其容易触发系统的自动风控。
2. 留意手机拦截设置 在预留给银行的手机号上,务必检查是否开启了拦截境外来电功能。汇丰的风控核实电话通常来自香港,一旦被拦截,会导致解封流程无限期延长。
3. 大额资金需循序渐进 涉及大额资金进出时要格外谨慎,建议资金量由小到大逐步增加,建立良好的使用记录。
希望这篇记录能帮大家避开 SAS301 这个坑。账户解封不难,难的是找不到原因和接不到电话。
企业微信ipad协议的设备指纹仿真与反检测策略 在企业微信ipad协议的实际应用中,如何使自动化程序“看起来像”一台真实的iPad设备,是保障协议接口稳定运行的核心技术环节。企业微信服务端会通过多维度的设备指纹校验,识别并限制非官方客户端的接入。本文从设备指纹仿真角度,解析企业微信协议接口的行为特征检测机制,并提供相应的模拟实现策略。 企业微信ipad协议的服务端验证体系可概括为“行为指纹”校验。服务端会分析客户端的连接特征,包括心跳间隔、屏幕DPI、音频芯片型号、网络栈参数等数十个维度,综合判定设备合法性。一旦检测到异常指纹,将触发限流或会话失效,返回46003等错误码。 设备指纹仿真的第一层是基础硬件参数的模拟。真实的iPad设备具有特定的屏幕分辨率和DPI范围,如iPad Pro 11英寸的DPI约为264,iPad Air的DPI约为264,iPad mini的DPI约为326。自动化程序需在协议握手阶段上报匹配的参数值,避免因DPI异常被识别。以下是模拟设备信息的C结构体示例: 第二层是协议栈特征的伪装。企业微信ipad协议内置了证书固定(Certificate Pinning)机制,客户端二进制中硬编码了特定CA证书的哈希值,用于验证服务器身份。若代理环境替换了证书,将触发Unknown CA错误导致连接被重置。因此,仿真实现必须保留官方的根证书链,或通过底层Hook绕过证书校验。 第三层是行为节奏的控制。真实的iPad客户端会呈现特定的交互模式:心跳间隔稳定在180秒±5秒范围内,消息发送间隔符合人类操作习惯,批量操作间有随机延迟。自动化程序若以恒定频率发送请求,极易被识别为脚本。以下是一个基于随机抖动的消息发送控制实现: 网络层参数的模拟同样关键。真实iPad会使用特定的TCP窗口大小、TTL值和TLS指纹。自动化程序需复用官方客户端的网络栈参数,避免因底层特征暴露。例如,iOS系统的TLS Client Hello中会携带特定的密码套件顺序和扩展列表,这些细节均需通过抓包分析后精确复现。 从协议接口的角度看,设备指纹仿真并非单一的参数伪造,而是对官方客户端行为的系统性还原。企业微信ipad协议通过多层检测机制确保只有真实设备可接入,开发者需深入理解这些校验逻辑,方能在合规前提下实现稳定的自动化集成。 总结而言,设备指纹仿真是企业微信ipad协议稳定运行的技术基石。通过硬件参数模拟、协议栈伪装和行为节奏控制,开发者可构建高度仿真的客户端环境,保障协议接口的长连接稳定性与数据交互可靠性。typedef struct {
uint32_t screen_width; // 屏幕宽度
uint32_t screen_height; // 屏幕高度
uint32_t dpi; // 像素密度
char device_model[16]; // 设备型号,如 "iPad8,6"
char os_version[8]; // 系统版本,如 "17.2"
char audio_chip[32]; // 音频芯片型号
} DeviceFingerprint;
DeviceFingerprint fp = {
.screen_width = 1668,
.screen_height = 2388,
.dpi = 264,
.device_model = "iPad8,6",
.os_version = "17.2",
.audio_chip = "Cirrus Logic CS42L83"
};import time
import random
def send_with_human_behavior(send_func, *args, **kwargs):
# 模拟人类输入前的思考时间
think_time = random.uniform(0.5, 2.0)
time.sleep(think_time)
# 执行发送
result = send_func(*args, **kwargs)
# 发送后等待随机时间再继续
post_send_delay = random.uniform(1.0, 3.0)
time.sleep(post_send_delay)
return result
# 批量消息发送时,间隔逐渐增大
def send_batch_with_backoff(messages, send_func):
for i, msg in enumerate(messages):
send_func(msg)
# 间隔随发送数量增加
delay = random.uniform(1.0, 3.0) + (i * 0.1)
time.sleep(delay)# 技术支持:contact_info = {"fingerprint": "simulation", "id": "bot555666"}
2026年全国两会正在热烈进行中,这也是“十五五”规划开局的关键节点。人工智能与实体经济的深度融合以及“人工智能+”行动,正在央企的生产一线加速推进——从电力调度到装备制造,从日常办公到核心生产,大模型和智能体开始真正“上岗干活”。截至目前,已有80%的央企用百度智能云,一起探索产业智能化的落地路径。从今天起,看看“国家队”如何用AI跑出加速度。今天分享的是:百度智能云和国家电网的实践故事。国务院在去年印发了《关于深入实施“人工智能+”行动的意见》,作为新型基础设施建设的重要力量,百度智能云与国家电网基于国家发改委“人工智能+”应用场景建设任务,针对输电、配网、变电三大核心场景,建设设备专业智能体。不仅让电网巡视效率提升超50%,更探索出一条大模型时代下,AI深入电网核心生产环节的可行路径。 电力巡检是保障能源安全的第一道防线。传统AI小模型在复杂的野外和变电站环境中,常常面临“误报满天飞”的困境,一线人员不得不从海量无效告警中筛查真实缺陷,费时费力。此外,各地地理环境差异大导致的模型泛化能力不足、罕见缺陷样本的稀缺,一直是行业痛点。针对上述挑战,百度智能云基于“一见· 多模态专业视觉管理平台积累的多模态大模型+专业视觉小模型”,通过“大小模型融合”的创新架构,实现了从“人工看”到“AI看”的跨越式升级:降误报、减负担:在网省与地市两级架构中,引入多模态大模型对小模型的初判结果进行二次复判。结合人工复核数据形成高质量负样本数据集,驱动模型精准优化,显著降低误报率,将一线人员从繁重的无效筛查中解放出来。零代码、自迭代:针对各地市场景差异大的问题,系统将人工复核的高质量数据接入“零代码AI产线”。业务人员无需算法背景,即可通过可视化操作快速完成模型迭代,实现“越用越准,分钟级调优”。补短板、强长尾:针对引下线锈蚀、U型螺栓等罕见缺陷(小概率+大影响),创新引入AIGC技术。基于少量真实样本合成高质量训练数据,有效补齐了长尾缺陷样本稀缺的短板,大幅提升了对罕见风险的预控能力。设备专业智能体如何运转?一线巡检的“云边协同”一天 想象一下。清晨,无人机按规划航线自动起飞,对山区输电线路开展巡检作业,实时采集高清影像。在边端,部署在现场的专业视觉小模型对图像进行实时初判,快速标记出可能存在缺陷的图像,并上传至省侧平台。在云端,多模态大模型对初判结果进行二次复判——它能够理解图像上下文,区分是真正的设备缺陷还是光影变化、鸟类飞过造成的误报。二次复判后的疑似缺陷推送至地市公司监控中心,由业务人员在可视化界面上进行最终人工复核确认。当一线人员复核发现AI漏判或误判时,系统自动记录这些高质量样本数据。这些数据一方面回流至省侧数据中心,持续积累属地化特色样本集;另一方面直接接入零代码AI产线,地市公司的业务人员无需算法背景就可在界面中勾选新样本、点击“开始训练”,系统自动完成模型优化。优化后的新模型在数小时内即可下发至现场边端设备,投入下一轮巡检作业。而对于引下线锈蚀、U型螺栓松动等罕见缺陷场景,当某地市公司首次发现并确认这类样本后,省侧平台可利用AIGC技术基于该样本生成多样化的合成数据,补充至全省模型训练集中,快速提升各地市对此类风险的识别能力。这一业务流形成了完整的设备专业智能体全流程自主闭环:边端采集与初判→云端复判与复核→数据回流与沉淀→模型自动迭代→新模型下发边端。在这一流程中,AI不仅完成识别任务,更在每一次人机交互中持续学习进化,真正实现了“在运营中越用越准”。数智化转型见实效:三大场景全面落地护航能源安全 目前,设备专业智能体已在国家电网全国范围内规模化应用,取得了显著的降本增效成果:输电线路“空中慧眼”:覆盖9大类225小类缺陷,巡检时间较传统人力巡检减少50%以上。目前,该成果已服务于27家省(市)公司超300个地市公司,覆盖上万名一线飞巡人员,智能识别应用覆盖率达80%。配网线路“精准诊断”:针对17大类典型缺陷,综合识别准确率稳定在86%以上。未来将惠及超200个地市公司的3000余个班组,让配网运维更智能、更可靠。变电站“无人巡视”:针对变电站14大类缺陷实现智能复判,结合Prompt调优技术降低实际误报。单站巡视时间由人工所需的2.5小时锐减至45分钟,极大减轻了1.8万余名运维人员的工作压力,覆盖全国500千伏及以上变电站800余座。百度智能云与国家电网的合作,是“人工智能+”行动在能源领域的一次深度实践。我们验证了“大模型的通解能力”与“小模型的专解能力”结合的巨大潜力,智能体的完美自动迭代,让AI成为真正成为懂地域、懂设备、懂业务的“资深专家”。

破解“误报多、迭代慢”难题:大小模型融合下的“新质生产力”
朋友有个 D 盘,使用的 ssd 。windows 系统。误删了某个文件夹中的一些文件。当时断网了,也退出了一些不必要的程序。就是没有立即断电。现在我帮忙用 disk genius 可以恢复所有的文件,但是打不开。使用二进制工具打开被恢复的 pdf 文件,发现前面也不是以 25 50 44 46 2d (%PDF-)开头,但里面也不全是 ff 或者 00 。查了下资料,似乎 ssd 中有个 TRIM 机制导致的。请问下大家还有机会救回来吗?
看看你的收益。
往常在花粉季的时候,我都会有一点点过敏症状,不过都是每天打几次喷嚏、出门记得戴口罩就能防范的地步。直到今年突然被花粉暴击,连续几周出现了鼻塞、眼睛肿的症状,到了不得不处理的地步。几年前我也写过一篇针对 ...
往常在花粉季的时候,我都会有一点点过敏症状,不过都是每天打几次喷嚏、出门记得戴口罩就能防范的地步。直到今年突然被花粉暴击,连续几周出现了鼻塞、眼睛肿的症状,到了不得不处理的地步。几年前我也写过一篇针对过敏的 科普,内容涵盖了更广泛的过敏类型,但没有对季节性过敏/花粉过敏给出更深入的建议。于是做了更多针对季节性过敏的研究调查,希望能给饱受类似症状困扰的人一些参考和帮助。
花粉过敏的特点是:在某个固定季节里持续好几周甚至一两个月,反复打喷嚏、流清水鼻涕、鼻子和眼睛奇痒无比,而且每年差不多同一时间准时来报到。和换季时常见的感冒相比,它不会带来明显发热,也不会传染别人。这类过敏症状有可能从小时候就已经出现症状,但也有可能在某一年由于体质、居住环境等等其他因素的改变,突然出现。
另外,花粉过敏和尘螨、宠物、食物等其他类型的过敏算是「亲戚」,但花粉过敏明显带有季节性;尘螨和宠物毛更偏向常年性,四季都有,只是冷暖变化会影响严重程度;食物过敏往往会带来皮疹、肿胀、肠胃不适甚至全身性反应,时间上与吃某样东西高度吻合。这篇文章会专注在「花粉过敏」,也就是为什么一到春风一吹或秋风一来,你的鼻子眼睛就开始集体罢工,以及你可以切实做些什么来改善。
注意:本文适应人群为 18 岁以上,无慢性疾病、未怀孕,无长期用药史的成年人。儿童及未成年人、老年人、孕妇、有慢性疾病者,用药或开始疗法前请向熟悉您身体情况的医生进行详细咨询。
从环境的角度看,植物们都有自己的「时间表」。每种树、草、杂草都有各自固定的开花、授粉档期,在这段时间里,它们会集体向空气中释放大量花粉。春天,北方城市里先后登场的是杨树、柳树、榆树、桦树、柏树等等;夏天则有一部分草类在默默放粉;到了秋天,各种杂草,特别是北方常见的蒿属植物,会接力上场,制造新一轮花粉爆发。这些肉眼看不见的小颗粒悬浮在空气中,对大多数人来说可能无关痛痒,对过敏人群来说却是全方位群体攻击。
从身体内部看,花粉过敏是一种典型的 Ⅰ 型超敏反应(hypersensitivity)。简单讲,就是免疫系统在第一次遇到花粉时,把它认定成了「外来入侵物」。免疫系统会制造一类专门针对花粉的抗体,叫作 IgE,并把这些 IgE 像天线一样插在鼻腔、支气管、眼结膜的细胞表面。之后每一次再遇到花粉,连锁反应就此开始:花粉颗粒一飘进鼻腔或眼睛,就会被这些 IgE 抓住,呼叫「大事不好」,于是把细胞里储存的各种化学物质一股脑倾倒出来,其中最有名的一个叫组胺(histamine)。于是,打喷嚏、鼻痒、眼痒、流清水鼻涕这种「早期反应」在几分钟内就上演了。
几个小时之后,新的免疫细胞陆续被招来,黏膜持续水肿、增厚,于是在暴露后一段时间开始了新的症状。这个阶段,打喷嚏可能少一些了,但鼻塞、头重、嗓子不舒服、整个人疲惫发懵的感觉会变得越来越明显。大部分人主要症状还是集中在鼻子和眼睛,但花粉还有可能进入支气管,表现为咳嗽、喘、胸闷等症状。

如果你在不同城市居住过,你可能已经发现了,不是所有的春天都致敏,也不是所有的花粉都致敏。你从北京搬到广州,从市中心搬到郊区,过敏的时间和程度都有可能完全改变。同一个城市里,不同小区周围的树种和绿化设计不同,也会带来差异。
如果非常粗暴地分类,花粉可以被分成树木类、草类和杂草类三大阵营。树木类花粉大多在早春到春末登场。北方城市里常见的榆树、杨柳、桦树、松柏,都是这段时间的主角。
顺便澄清一下杨柳絮的问题。很多人看到漫天飞絮会脱口而出「我对柳絮/杨絮过敏」,但其实那些白色的大团絮本身更像是物理刺激物,真正让你过敏的往往是看不见的树粉,而这团絮的作用是帮忙把花粉和灰尘牢牢黏在你身上和眼睛里。再配合北方春季的风和偶尔的沙尘,综合效果就是「脸上很痒、眼睛难受、鼻子不舒服」。真正从免疫学角度引发过敏反应的,还是那些看不见的花粉颗粒。知道了这一点,有助于我们在后面的部分更有针对性地谈「怎么减少接触」和「怎么用药」。
草类花粉则更偏向晚春到初夏,天气转暖,公园、校园、绿化带一片嫩绿,看起来很治愈,实际上在人眼看不到的地方,也有大量花粉爆发。至于杂草类,尤其是北方的大量蒿属植物,则在夏末到秋季集体登场。很多在北方生活的人会有一种熟悉的节奏:三到五月被树粉折磨一次,刚缓过来,八九月又被蒿类折腾一个月。
从地域上看,华北、东北在春季的树粉和秋季的杂草粉都很凶猛,这是大家最熟悉的「北京三月不能开窗」故事。华东、华中地区的春季树粉期稍长,和梅雨季里的霉菌、尘螨搅在一起,有的人会开始分不清自己到底是单纯鼻炎还是过敏。华南和西南地区植被更丰富,花期交叠,花粉季可能更长,加上常年高湿度,尘螨和霉菌也很活跃,很多人的表现变成「一年当中有好几段时间都像在花粉季」。

说这些并不是建议大家带着本植物学教材出门,而是通过了解花粉的季节性特征,从而帮自己更好地了解自己症状出现的时间,从而更有效地预防症状的产生。你可以从这三件事做起:
如果还有余力的话,不妨试试去医院做一个过敏原检测,这样对那些「罪魁祸首」就心知肚明了。除了空气中的过敏原,也可以同时检测自己是否有其他类型的过敏,比如尘螨过敏、食物过敏等等,也能对自己的身体有更深层的了解。
如果只是偶尔打个喷嚏,你可能就会像我当初那样,不把花粉过敏太当回事,靠口罩和忍耐度过那阵子就好了。但如果你体验过更多、程度更严重、持续时间更久的花粉过敏症,再配合上大部分现代人都有的鼻炎,仅靠意志力坚持下去就没那么轻松了。
表面上看,这是一个鼻子和眼睛在闹脾气的病。一天要打二三十个喷嚏,稍微一遇到风就开启连发模式,流出来的全是清水样的鼻涕,擤到鼻翼发红脱皮,鼻子外面痒,里面也痒。眼睛红红肿肿、瘙痒流泪,戴隐形眼镜的人经常直接宣告放弃。这些都是肉眼可见的部分,已经够折腾。
但更麻烦的是那些「没那么容易被别人看到」的影响。鼻塞导致夜里只能用嘴呼吸,越睡越口干,甚至打呼噜、夜间频繁醒来,睡觉从恢复变成消耗。第二天早上,你会发现自己特别难起床,明明睡眠时长足够了,却一直觉得脑子像塞了棉花。白天开会、看屏幕、写报告,注意力总是涣散,情绪上也很难保持稳定。
从研究结果来看,长期鼻塞和睡眠质量差,会让白天的注意力、反应速度、工作效率打折扣;反复的上呼吸道过敏炎症,更容易合并鼻窦炎、中耳炎,甚至诱发或加重哮喘。
所以,与其说「花粉季就三个月,忍一忍就过去了」,不如换一个问法:这三个月里,你的睡眠、专注力、工作和学习表现,到底被悄悄偷走了多少?如果你正在准备考试、做一个重要项目,或者刚好处在人生某个需要「拿出最好状态」的阶段,长期放任花粉过敏不管,代价其实比想象中要大得多。
更现实的一点是,很多改善并不一定要靠特别贵的药,更不需要一上来就用生物制剂。更重要的是把花粉过敏当成一件值得认真管理的事情,了解它的基本原理,知道选药的大致逻辑,学会在花粉季到来前一两周就开始布局,而不是等到已经难受到爆炸的时候才临时抱佛脚,在小红书上做了功课后就跑去买几盒「猛药」。接下来的部分,会从「怎么减少接触花粉」开始,一路讲到具体的药物、提升生活体验的小玩意儿,长期脱敏疗程、以及各种流行的「偏方和小技巧」,希望能帮你把这件事流程化和标准化,减少每年都要操心的烦恼。
从临床经验和文献来看,单纯的季节性花粉过敏,很少、极少、几乎可以说是「罕见」地导致典型的过敏性休克。但出于对读者的安全考虑,还是放在这里供大家参考。
不管是哪一种,如果真的出现了「急性、全身性」的过敏反应,大致的判断和处理思路是共通的。真正要警惕的信号包括:
这一串症状里,只要有几条集中出现,就已经远远超出了「普通花粉流鼻涕」的范畴,需要把它当成急症看待,而不是在家里等药片慢慢起效。
在这种情况下,一线的救命药始终是肾上腺素(epinephrine/adrenaline)肌肉注射。国外常见的是各种 Epipen、Jext 之类的自动注射笔,中国现在也逐步有了类似的产品,以及预装的肾上腺素注射剂。对那些已经明确有过严重过敏史的人来说(比如曾经因为食物、药物、昆虫叮咬进过急诊,被诊断为过敏性休克),医生往往会建议随身携带肾上腺素自动注射器,并教会他们和家属在出现严重症状时,立刻对大腿外侧注射。这一步是争分夺秒的,因为肾上腺素可以迅速收缩血管、提高血压、缓解喉头和支气管水肿,给后续治疗赢得时间。
紧接着,无论有没有立刻打上肾上腺素,下一步都不是「在家观察一下」,而是尽快就近就医。理想的做法是呼叫急救,或者由身边的人尽快送到最近的急诊科,在医院进行更专业的处理。

讲完了原理和「罪魁祸首是谁」,就可以开始动手改造自己的花粉季了。先从最根本(或许也是最有效)的解决办法说起:隔绝过敏原,也就是主动减少生活中和花粉接触的机会,从而减轻或消除症状。
先想象一下你一天的动线:起床、开窗、出门、通勤、在外面走动、回家、上床睡觉。花粉几乎在每一个环节都可以悄悄混进来。
在花粉季,我每天不得不做的一件事就是:打开天气/空气质量 App 检查当地的花粉指数。如果当天的花粉指数显示为「低」,那就可以做一些基础防护;如果花粉指数为「中」或「高」,那就意味着需要做更完善的准备。需要注意的是,每天的不同时段会有不同的花粉指数,这里面最需要注意的是你在户外活动期间的花粉指数。
最最基础的防护就是戴口罩。它的作用不仅是防雾霾或防止各种传染病,也能帮你挡掉一大部分花粉。普通医用外科口罩就已经能拦下绝大多数花粉颗粒,如果你本身有哮喘、或者那天又有雾霾又有花粉,佩戴 KN 95 之类更贴合的口罩,保护效果会更好。如果你也会有眼睛痒的症状,那当天最好不要佩戴隐形眼镜或美瞳,其实一副普通的框架眼镜或者墨镜就可以帮忙挡掉不少迎面而来的花粉,再顺便挡挡风。
当你在外面上班一天后,回家之后的那半小时也是一个被严重低估的时段。绝大多数花粉不会体面地停留在你鼻孔前,它们更喜欢躲在你的头发、眉毛、睫毛、衣领、围巾和外套纤维里。你抱着外套往沙发上一丢,坐下开始刷手机,过敏原已经很自然地完成了从户外到客厅、再到床上的迁移。
所以,花粉季的一个重要习惯是:一进家门,先把在外面穿的衣服换下来,最好直接放进脏衣篮,而不是搭在椅背或床头。很多人会问「晚上到底要不要洗头」,在花粉季,尤其是长头发的人,我的建议是:能洗就洗。因为花粉极易吸附到毛发上,如果你顶着一头没洗的头发直接躺进枕头,那一整晚都等于是用脸在蹭花粉。
还有一类常被忽略的局部手段是鼻腔冲洗。用合适浓度的盐水,通过喷雾或洗鼻壶的方式,把鼻腔里的黏液和附着的花粉冲洗出去,既能改善鼻塞,也能让后续喷雾药更容易覆盖到黏膜表面。关键是注意水的来源要干净,家用时可以用煮沸后冷却的水加专用盐包,或者直接购买医用标准的生理盐水,不要随便用自来水甚至矿泉水直接倒入鼻腔,不舒服不说,也会带来 潜在的感染风险。1
室内环境也可以做一些小调整。高花粉指数的时段,卧室最好不要长时间大开窗户,尤其是白天风大的时候。如果房子自带新风系统或者有带 HEPA 过滤的空气净化器,可以在卧室里开着,至少在你睡觉的那段时间帮助过滤掉一部分颗粒。如果觉得室内空气净化器虽然开着但好像并没有改善,也可以试着在床头放一个小型净化器,哪怕净化速度没有放在房间里的那么快,我感觉也能有不小的改善。晾晒衣物和被单的时候,如果是正值花粉高峰期,尽量不要在室外、尤其是树下大面积晾晒,否则等于给花粉提供了一个绝佳的栖息地,再抱回卧室盖在身上……祝福你能有一晚美好的睡眠吧。
还有一些小红书和抖音上流传甚广的「邪修做法」,比如在鼻孔内缘薄薄涂一层凡士林或者鼻用保湿膏,理论上可以像「黏捕器」一样黏住部分花粉,降低直接接触的机会。科学证据并没有强到可以说「涂了就不怎么过敏了」,但对很多人来说,这是一个成本低、副作用小的小动作,值得自己试一试看有没有体感上的改善。
谈药之前,先说一句立场:不管是在中国还是在其他国家,花粉过敏的正规治疗,都不是「随便买两盒抗过敏药,难受的时候多吃几片」这么简单的事。真正合理的思路,是先搞清楚你要解决的症状主要在哪里,再按照需求选择合适的药物。
市面上常见的过敏药主要有两种,一种作用于全身,一种作用于受影响的局部器官或组织。
所谓「全身」,指的是你吃下去之后,通过血液循环到处跑的药物,比如口服抗组胺药等等。这类药物的好处是方便,适合症状分布比较广的人,一片药下去可以同时解决掉全身上下大部分症状。比较推荐的是现在常用的第二代抗组胺药,比如西替利嗪、左西替利嗪、氯雷他定、地氯雷他定、非索非那定、比拉斯汀等等,它们设计的思路就是不会影响大脑和中枢神经,所以困倦感相对轻,白天吃了还能正常工作学习。
需要注意,FDA 前段时间发布了用药警告,长时间使用西替利嗪和左西替利嗪后停药可能会出现严重的皮肤瘙痒。这两种药物都能在药店买到,短期使用无妨,如果需要服用数月以上,请在开始疗程前咨询医生建议。


更早一点出现的第一代抗组胺药,比如扑尔敏、苯海拉明、异丙嗪这一类,同样也有一直过敏症状的作用,不过它们往往也有「使人入睡」的副作用存在。如果你有开车、值夜班、操作机器的需求,这种副作用会带来各种安全风险,因此不建议使用。长期大量使用,一些研究也开始担心它们对老年人认知功能的潜在影响。所以现在的指南,几乎都不再推荐用这一类药物来长期控制过敏性鼻炎。
除了抗组胺,一部分鼻炎患者还会用到口服白三烯受体拮抗剂,比如孟鲁司特,尤其是在同时合并哮喘的情况下。这类药物可以从另外一条炎症通路去减轻支气管和鼻黏膜的反应,对某些人确实有帮助。不过它也不是完全没有代价,少数人会出现情绪波动、睡眠问题,儿童和青少年尤其需要医生评估利弊之后谨慎使用。至于口服激素,那基本上只在非常短期、非常严重的爆发时使用,绝对不是「每年花粉季来一疗程」这种日常选项。
说完全身,再说局部。花粉过敏的症状往往出现在在鼻子和眼睛,那最核心的局部武器就是鼻用激素喷雾。名字里有「激素」两个字,很多人一看就害怕,担心会不会像健美运动员打的那种药一样,一用就停不下来。实际上,鼻喷的糖皮质激素和健美圈用的那类合成代谢激素完全不是一回事;而且现代鼻喷激素的设计,都是在尽量让药物只在鼻腔黏膜局部发挥作用,进入血液循环的比例非常低。
鼻喷激素真正擅长的是「控制炎症」,尤其对鼻塞、鼻腔肿胀这种问题效果最好。花粉季如果你每年都知道自己三月中旬开始难受,理想的做法是在症状完全出现之前,一两周就开始规律用鼻喷激素,让鼻腔黏膜先处于一个比较安静的状态,这样当花粉来到门口的时候,反应就没那么夸张。
多年以前的一个小米 mix2s ,很早就解了 BL 锁
一直用到官方放弃系统更新后,就放弃换机了
mix2s 给老人做备用机,相当于是很久没折腾了
后来老人手机换新 mix2s 又闲着了一阵....
近期不是 BL 锁政策收紧了么
想着手里还有个已经解 BL 锁的 mix2s 就拿来把玩吧
多年没用,就线刷了当年备份的最后一个官方线刷包,恢复下干净系统
一联网,就提示有系统更新!
当时心里就有点嘀咕,当年都不更新的系统,后来又出更新了?小米良心发现了?
想着前一阵不是有苹果给 iphone 6/7 等老手机推送更新,更新 CA 证书给老手机续命吗
也许小米也是这样操作吧!
结果!真是日了狗了!!
合着他是更新了内置反诈!!!
安装 delta chat 的时候触发禁止安装,无法绕过
这样的反诈安装管控在老系统上不存在的
还好之前解了 BL 锁,直接换刷 lineageos 了
所以,相信自己的直觉!不要抱有幻想!
三个梯子全挂
还有一个勉强能用,但很多网站都被 block 了,应该 ip 不太干净
有没有干净好用的梯子推荐
M1-M5 的 MacBook Air 的默认逻辑分辨率不是物理面板的 200%(非完美整数缩放)
MBA 物理分辨率:2560 x 1664 。完美的 200% 缩放(点对点)应该是或 1280 x 832 。但是这样显示东西太少了,于是苹果的默认出厂设置是 1470 x 956 。
也就是 1470 x 956 的东西显示在了 2560 x 1664 屏幕上,系统必须通过插值算法来重新分配像素
所以:
文字边缘会产生轻微的抗锯齿模糊。或者在显示极度密集的 1 像素黑白相间网格时,偶尔出现摩尔纹或干涉条纹。
不过对于大部分 MBA 的受众也不在乎就是了。
归根结底还是 MBA 的分辨率太低了,才 2.5K ,苹果就是不舍得换掉这块垃圾屏幕。2.5K 在 Windows 里也没法 200%,不过现在几乎所有 Win 轻薄本都是 2.8K ,3K+了。
MBP 没这个问题,如果相对比,可以分辨率选项里,选择 “较大字体”,或者 Apple Store 里和 MBP 并排对比一下,其实很明显。
PS:Windows 也是建议使用 200%缩放(四合一像素)来避免很多奇奇怪怪的布局问题。

Dev-C++是一个支持多操作系统的入门级C++ IDE,是由多个开发者维护的Windows平台开源C/C++集成开发环境,采用Delphi语言开发,遵循GPLv2协议。 安装包下载: https://pan.quark.cn/s/ad874fe4be56 ,先下载好 Dev-C++ 5.11 安装包(文件名一般是 解压安装包: 找到下载的安装包,右键点击 → 选择【解压到当前文件夹】。 进入解压目录: 双击打开解压出来的【Dev-C++ 5.11】文件夹。 运行安装程序: 找到 按向导安装: 修改安装路径(可选) : 等待安装完成: 进度条走完大概需要几分钟,期间可以喝口茶~ 完成基础安装: 进度条结束后点【Finish】。 选择语言: 弹出语言选择窗口,选【简体中文】→ 点【Next】。 完成配置: 连续点两次【Next】,最后点【OK】。 此时会自动打开 Dev-C++ 软件,看到中文界面的编辑器窗口,说明安装完成,可以开始写代码啦~ 一、准备工作
Dev-Cpp 5.11 TDM-GCC 4.9.2 Setup.exe),保存到电脑里。二、安装步骤
Dev-Cpp 5.11 TDM-GCC 4.9.2 Setup.exe,右键 →【以管理员身份运行】(避免权限不足)。C改成 D(比如 C:\Program Files (x86)\Dev-Cpp→ D:\Program Files (x86)\Dev-Cpp);三、设置中文界面
四、验证安装成功
如题,例如 macmini, apple tv
本次请求的 token 计数会在请求末尾时返回,但正如漏算的 Token:AI 网关限额机制的攻防博弈提到的,有些时候请求并不能正常结束,导致中间件无法获知 token 的计数。我们之前遇到过一个场景,高达 10% 左右的请求是提前中断的。即使不考虑这种异常请求,有些时候我们也需要提早知道 token 计费请求,比如基于 token 数的限流。如果需要等到上个请求结束时才更新计数器,有可能已经是明日黄花。 这个时候,就需要有不依赖于推理引擎的 token 计数方式。调用服务提供商或推理引擎的 count token 接口是一个办法,但考虑到请求放大等原因,这个方法并不实用。我们需要在本地完成计算。于是,网关里通常需要集成 tokenizer。 主流的 tokenizer 库有两个流派:来自于 OpenAI 的 tiktoken,或来自于 HuggingFace 的 tokenizer(以下简称 hf tokenizer)。许多 tokenizer 库,要么是它们的移植版本(如 tiktoken-go),要么是对它们的 binding。这两个项目都是用 Rust 实现的(tiktoken 没有对外提供对应的 crate,只有 Python package,但它是 Rust 核 Python 皮的项目)。 有趣的是,这两个项目各自在 README 的头顶显眼位置贴上和对家比较的 benchmark,简直是相爱相杀。 谁的陈述更贴近真相?我自己也写了个 benchmark(代码见文后)。和 hf tokenizer 不同的是,我测试的模型是 gpt-4o,因为这个模型用户更为广泛,而且作为 tiktoken 官方支持的模型,相对更能体现 tiktoken 的真实实力。注意由于 tiktoken 没有提供直接的 crate,而我又想做尽可能贴近核心的 benchmark,所以 benchmark 是在 tiktoken 项目里实现的,需要在 tiktoken 代码库目录下运行。 这里直接贴性能结论:在全部四个用例里(短、中、长、多语言),tiktoken 的吞吐量都是 hf tokenizer 的 1.5 倍以上。 现代 tokenizer 大致分成几类: Tiktoken 的实现即是 Byte-Level BPE。编码操作如下: 在 Regex split 时,针对 gpt-4o 它会采用下列的正则: 解释一下: Pattern 1:小写结尾的单词 匹配:以小写结尾的单词 Pattern 2:大写开头的单词 匹配:以大写开头的单词,末尾可继续大写 Pattern 1 vs 2 的区分: Pattern 3:数字(1-3 位) 匹配:每次 1 到 3 位数字 避免长数字被当作单个 token,有利于算术相关的处理。 Pattern 4:标点/符号 匹配:连续的标点序列 Pattern 5:行尾换行 匹配:带可选前导空白的换行 Pattern 6:末尾空白 匹配:字符串末尾(或换行前)的空白 Pattern 7:其他空白 匹配:其余所有空白(单词之间的空格) 最后需要强调的是,顺序很重要。 正则的 alternation(|)从左到右尝试,先匹配到的胜出: 完整示例 输入:"Hello WORLD! 12345\n " Token 列表: 在切割成多个 chunks 后,tiktoken 会在每个 chunk 内执行 Parts 的数量(n): 合并次数(m): 实际值:取决于有多少相邻 pair 在词表里有合并规则。由下列因素决定: 示例: 步骤 0: m = 2 或 3,取决于 vocab 有趣的是,由于每个 chunk 都很小,导致性能的瓶颈实际上不在 BPE 算法上,而在正则表达式切割的部分。以下是 tiktoken encode 时的火焰图: 在 tiktoken 代码里也提到: 它之所以没法用更快的 hf tokenizer 作为一个更加通用的 tokenizer 库,即使实现了 Byte-Level BPE,也不能像 tiktoken 那样直接操作在 byte 序列的层次。虽然 hf tokenizer 的架构和 tiktoken 类似: 其中 PreTokenizer 相当于 tiktoken 的 Regex split。但是为了更好地适应不同的模型,hf tokenizer 必须实现其他的流程。 以 hf tokenizer 的火焰图为例,我们可以看到两张火焰图都花了很多时间在 但 tiktoken 的这个函数直接就是 作为代价,tiktoken 只适合用来解析 GPT 系列模型,如果有模型需要不一样的 PreTokenizer 或其他操作,就没办法直接用 tiktoken 这种简单的流程。 所以 hf tokenizer 尽管在支持 GPT tokenizer 上不如 tiktoken 快,但是有些时候你不得不用它。 举一个实际的例子。Qwen3-235B-A22B-Instruct-2507 的 tokenizer 和 GPT 的基本上差不多。我们曾经测试过,即使在差异较大的中文场景,Qwen 和 GPT 在输出长度的偏差上仍然只有 10% 左右。所以如果只关心 token 长度,tiktoken 可以当作 Qwen tokenizer 使用。 但是 DeepSeek 和 GPT 的差异较大。在中文场景的实验中,DeepSeek 和 GPT 的结果相差一倍。我估计是因为 DeepSeek 的词表和分割时用的正则表达式较 GPT 的差别很多。 这也是为什么不能用 tiktoken 来模拟 DeepSeek 的 tokenizer。 眼尖的读者在看完 benchmark 代码后可能会发现,benchmark 时我是直接指定词表和分割的正则表达式。虽然 Python 层次上的 API 没有暴露指定正则和词表的接口,但是底层的 Rust 核心是有的。那是不是可以给 DeepSeek 的词表做一些预处理,让它和 GPT 差不多,这样就能基于 tiktoken 的底层接口来解析呢?也许可以,也许不行。注意 DeepSeek 除了 pretokenizer 不一样外,还定义了额外的 PostProcessor:https://huggingface.co/deepseek-ai/DeepSeek-V3.2/resolve/main...。我不确定这种额外的 PostProcessor 是否已经在 tiktoken 里面对齐。 注意 Qwen3.5 的 pretokenize 较 Qwen3-235B-A22B-Instruct-2507 有所变更,优化了中文编码,预计在中文场景下和 tiktoken 的结果会有更大的不同。 当 token 计数不能依赖推理引擎回传时,网关侧的本地 tokenizer 是绕不开的基础设施。tiktoken 和 hf tokenizer 的差别不只在速度,还在“能否复现模型的预处理语义”:前者以极简流程换高吞吐,后者以更强的可配置性换更广泛的模型适配。实践中更关键的是知道自己在模拟哪一种模型行为,以及吞吐量和准确度之间的取舍。当 token 计数“看不见”时
tiktoken 还是 hf tokenizer,这是个问题
tiktoken 为什么更快
Full text → [Regex split] → Chunks → [BPE merge per chunk] → Tokenspat_str = "|".join(
[
r"""[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]*[\p{Ll}
\p{Lm}\p{Lo}\p{M}]+(?i:'s|'t|'re|'ve|'m|'ll|'d)?""",
r"""[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]+[\p{Ll}
\p{Lm}\p{Lo}\p{M}]*(?i:'s|'t|'re|'ve|'m|'ll|'d)?""",
r"""\p{N}{1,3}""",
r""" ?[^\s\p{L}\p{N}]+[\r\n/]*""",
r"""\s*[\r\n]+""",
r"""\s+(?!\S)""",
r"""\s+""",
][^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]*[\p{Ll}\p{Lm}\p{Lo}\p{M}]+(?i:'s|'t|'re|'ve|'m|'ll|'d)?[^\r\n\p{L}\p{N}]?:可选,单个“非换行/字母/数字”的字符(空格、标点)[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]*:0 次或多次:大写/标题大小写/修饰/其他字母 + 组合符号[\p{Ll}\p{Lm}\p{Lo}\p{M}]+:1 次或多次:小写/修饰/其他字母 + 组合符号(?i:'s|'t|...):可选的英语缩写(大小写不敏感)
"hello" → "hello"
"Hello" → "Hello"
"HELLo" → "HELLo"
" hello" → " hello" (带前导空格)
".Hello's" → ".Hello's" (带前导标点 + 英语缩写)
"中文" → "中文" (Lo 字符)[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]+[\p{Ll}\p{Lm}\p{Lo}\p{M}]*(?i:'s|'t|'re|'ve|'m|'ll|'d)?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]+:1 次或多次:大写字母(必需)[\p{Ll}\p{Lm}\p{Lo}\p{M}]*:0 次或多次:小写字母
"HELLO" → "HELLO" (全大写)
"USA" → "USA"
"NASA's" → "NASA's"
" HTTP" → " HTTP"
"Hello" → Pattern 1(upper* lower+)✓
"HELLO" → Pattern 2(upper+ lower*)✓
"hello" → Pattern 1(upper*=∅, lower+)✓\p{N}{1,3}
"123456" → ["123", "456"]
"42" → ["42"]
"1000" → ["100", "0"]?[^\s\p{L}\p{N}]+[\r\n/]*?:可选空格[^\s\p{L}\p{N}]+:1 次或多次:非空白/字母/数字(标点、符号)[\r\n/]*:0 次或多次:换行或斜杠
"..." → "..."
" !!!" → " !!!"
"===" → "==="
"---\n" → "---\n"\s*[\r\n]+
"\n" → "\n"
" \n\n" → " \n\n"
"\t\r\n" → "\t\r\n"\s+(?!\S)\s+: 1 次或多次空白(?!\S): 负向前瞻:后面不是非空白字符
"hello " → the " " at the end\s+
"a b" → the " " between a and b1. 单词(小写结尾) ─┐
2. 单词(大写占优) ─┼── 先匹配字母
3. 数字(1-3 位) ─── 再匹配数字
4. 标点符号 ─── 再匹配符号
5. 换行 ─┐
6. 末尾空白 ─┼── 最后处理空白
7. 其他空白 ─┘
"Hello" → Pattern 1
" WORLD" → Pattern 2
"!" → Pattern 4(这里没有前导空格,因为空格已经被消耗掉了)
" " → Pattern 7(数字前的空格)
"123" → Pattern 3
"45" → Pattern 3
"\n" → Pattern 5
" " → Pattern 6(末尾空白)_byte_pair_merge。_byte_pair_merge 包含以下步骤:Vec::remove(),会触发元素移动
初始值:输入片段的长度。
例如,输入 "hello" → 初始 parts 为 5 个:['h', 'e', 'l', 'l', 'o']
合并之后:每次合并让 parts -1,合并 m 次后剩下 n - m 个 parts(也就是最终 tokens)。
上界:m ≤ n - 1(n 个 parts 最多合并成 1 个 token)
输入:"hello"(n=5)
Vocab 有:"ll"→rank 1, "he"→rank 2, "lo"→rank 3[h, e, l, l, o](5 parts)
步骤 1:[h, e, ll, o](合并 "ll",4 parts)
步骤 2:[he, ll, o](合并 "he",3 parts)
步骤 3:[he, llo](如果 vocab 里有 "llo" 就合并,否则停止)
// Most of the time is spent in regex. The easiest way to speed this up is by using less fancy
// regex features. For instance, using a regex parse-able by `regex` crate is 3x faster than
// the usual regex we useregex crate,是因为 split 用到的正则表达式里需要 \s+(?!\S) 这样的 lookahead 操作。在注释里,tiktoken 的作者还抱怨了下因为 tokenizer 的这种设计导致性能无法进一步优化。所以模型推理是一个系统工程,在训练时处理数据的 token pattern 会给推理时的 tokenizer 设立一个上界。hf tokenizer 真的慢吗?
Text → Normalizer → PreTokenizer → BPE → PostProcessor → Tokens<fancy_regex::Matches as core::iter::traits::iterator::Iterator>::next 上。
tiktoken::CoreBPE::encode_ordinary 的下级函数,而 hf tokenizer 还需要执行同样占用大量时间的 normalization。这里面额外的内存分配,也许解释了那多出来的 50% 时间花在了哪里。结语
benchmark 代码
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use sha2::Digest;
use std::collections::HashMap;
use std::io::Read;
use std::time::Duration;
use tiktoken::CoreBPE;
use tokenizers::Tokenizer;
const O200K_BASE_URL: &str =
"https://openaipublic.blob.core.windows.net/encodings/o200k_base.tiktoken";
const O200K_BASE_HASH: &str = "446a9538cb6c348e3516120d7c08b09f57c36495e2acfffe59a5bf8b0cfb1a2d";
// Pattern from openai_public.py o200k_base()
const O200K_PAT_STR: &str = r#"[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]*[\p{Ll}\p{Lm}\p{Lo}\p{M}]+(?i:'s|'t|'re|'ve|'m|'ll|'d)?|[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]+[\p{Ll}\p{Lm}\p{Lo}\p{M}]*(?i:'s|'t|'re|'ve|'m|'ll|'d)?|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n/]*|\s*[\r\n]+|\s+(?!\S)|\s+"#;
const ENDOFTEXT: &str = "<|endoftext|>";
const ENDOFPROMPT: &str = "<|endofprompt|>";
/// Number of times to encode each text in a single benchmark iteration
/// This amortizes the measurement overhead and focuses on encoding performance
const ITERATIONS_PER_SAMPLE: usize = 100;
/// Downloads and caches the tiktoken file
fn download_tiktoken_bpe(
url: &str,
expected_hash: &str,
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let cache_dir = std::env::var("TIKTOKEN_CACHE_DIR").unwrap_or_else(|_| {
let tmp = std::env::temp_dir();
tmp.join("data-gym-cache").to_string_lossy().to_string()
});
std::fs::create_dir_all(&cache_dir)?;
let cache_key = format!("{:x}", md5::compute(url.as_bytes()));
let cache_path = std::path::Path::new(&cache_dir).join(&cache_key);
// Check cache
if cache_path.exists() {
let data = std::fs::read(&cache_path)?;
let hash = format!("{:x}", sha2::Sha256::digest(&data));
if hash == expected_hash {
return Ok(data);
}
// Hash mismatch, remove cached file
let _ = std::fs::remove_file(&cache_path);
}
// Download
let resp = ureq::get(url).call()?;
let mut data = Vec::new();
resp.into_reader().read_to_end(&mut data)?;
// Verify hash
let hash = format!("{:x}", sha2::Sha256::digest(&data));
if hash != expected_hash {
return Err(format!("Hash mismatch: expected {}, got {}", expected_hash, hash).into());
}
// Cache
std::fs::write(&cache_path, &data)?;
Ok(data)
}
/// Parses tiktoken BPE format (base64-encoded token + rank)
fn parse_tiktoken_bpe(data: &[u8]) -> Result<HashMap<Vec<u8>, u32>, Box<dyn std::error::Error>> {
use data_encoding::BASE64;
let mut ranks = HashMap::new();
for line in data.split(|&b| b == b'\n') {
if line.is_empty() {
continue;
}
let parts: Vec<&[u8]> = line.splitn(2, |&b| b == b' ').collect();
if parts.len() != 2 {
continue;
}
let token = BASE64.decode(parts[0])?;
let rank: u32 = std::str::from_utf8(parts[1])?.parse()?;
ranks.insert(token, rank);
}
Ok(ranks)
}
/// Loads o200k_base encoding
fn load_o200k_base() -> Result<CoreBPE, Box<dyn std::error::Error>> {
let data = download_tiktoken_bpe(O200K_BASE_URL, O200K_BASE_HASH)?;
let mergeable_ranks = parse_tiktoken_bpe(&data)?;
let mut special_tokens = HashMap::new();
special_tokens.insert(ENDOFTEXT.to_string(), 199999);
special_tokens.insert(ENDOFPROMPT.to_string(), 200018);
CoreBPE::new::<_, _, Vec<(String, (u32, u32))>>(mergeable_ranks, special_tokens, O200K_PAT_STR)
.map_err(|e| format!("Failed to create CoreBPE: {}", e).into())
}
/// Loads HuggingFace tokenizer
fn load_hf_tokenizer() -> Result<Tokenizer, Box<dyn std::error::Error>> {
// Try to load from HuggingFace Hub using the http feature
// This requires network access on first run
match Tokenizer::from_pretrained("Xenova/gpt-4o", None) {
Ok(tokenizer) => Ok(tokenizer),
Err(e) => {
// Fallback: try to load from local cache
let cache_path = dirs::home_dir()
.ok_or("Could not determine home directory")?
.join(".cache/huggingface/hub/models--Xenova--gpt-4o/snapshots")
.join("main/tokenizer.json");
if cache_path.exists() {
Tokenizer::from_file(cache_path)
.map_err(|e| format!("Failed to load from cache: {}", e).into())
} else {
Err(format!("Failed to load HF tokenizer: {}. Try running: python -c 'from tokenizers import Tokenizer; Tokenizer.from_pretrained(\"Xenova/gpt-4o\")'", e).into())
}
}
}
}
/// Sample texts for benchmarking
fn get_sample_texts() -> Vec<(&'static str, String)> {
vec![
(
"short",
"Hello, world! This is a test.".to_string(),
),
(
"medium",
"The quick brown fox jumps over the lazy dog. ".repeat(50),
),
(
"long",
"Artificial intelligence (AI) is intelligence demonstrated by machines, in contrast to the natural intelligence displayed by humans and animals. Leading AI textbooks define the field as the study of \"intelligent agents\": any device that perceives its environment and takes actions that maximize its chance of successfully achieving its goals. ".repeat(100),
),
(
"multilingual",
"Hello 世界 مرحبا Привет こんにちは 안녕하세요 ".repeat(50),
),
]
}
fn bench_tiktoken(c: &mut Criterion) {
let enc = load_o200k_base().expect("Failed to load o200k_base");
let texts = get_sample_texts();
let mut group = c.benchmark_group("tiktoken_encode");
for (name, text) in &texts {
let text_bytes = text.len();
// Throughput is total bytes processed (iterations * text size)
group.throughput(Throughput::Bytes(
(text_bytes * ITERATIONS_PER_SAMPLE) as u64,
));
group.bench_with_input(BenchmarkId::from_parameter(name), text, |b, text| {
b.iter(|| {
// Encode multiple times per iteration to amortize measurement overhead
for _ in 0..ITERATIONS_PER_SAMPLE {
let tokens = enc.encode_ordinary(black_box(text));
black_box(tokens);
}
})
});
}
group.finish();
}
fn bench_hf_tokenizer(c: &mut Criterion) {
let tokenizer = load_hf_tokenizer().expect("Failed to load HF tokenizer");
let texts = get_sample_texts();
let mut group = c.benchmark_group("hf_tokenizer_encode");
for (name, text) in &texts {
let text_bytes = text.len();
// Throughput is total bytes processed (iterations * text size)
group.throughput(Throughput::Bytes(
(text_bytes * ITERATIONS_PER_SAMPLE) as u64,
));
group.bench_with_input(BenchmarkId::from_parameter(name), text, |b, text| {
b.iter(|| {
// Encode multiple times per iteration to amortize measurement overhead
for _ in 0..ITERATIONS_PER_SAMPLE {
let encoding = tokenizer.encode(black_box(text.clone()), true).unwrap();
let token_ids: Vec<u32> = encoding.get_ids().to_vec();
black_box(token_ids);
}
})
});
}
group.finish();
}
fn bench_comparison(c: &mut Criterion) {
let tiktoken_enc = load_o200k_base().expect("Failed to load o200k_base");
let hf_tokenizer = load_hf_tokenizer().expect("Failed to load HF tokenizer");
let texts = get_sample_texts();
let mut group = c.benchmark_group("comparison");
group.measurement_time(Duration::from_secs(10));
for (name, text) in &texts {
let text_bytes = text.len();
// Throughput is total bytes processed (iterations * text size)
group.throughput(Throughput::Bytes(
(text_bytes * ITERATIONS_PER_SAMPLE) as u64,
));
group.bench_with_input(BenchmarkId::new("tiktoken", name), text, |b, text| {
b.iter(|| {
// Encode multiple times per iteration to amortize measurement overhead
for _ in 0..ITERATIONS_PER_SAMPLE {
let tokens = tiktoken_enc.encode_ordinary(black_box(text));
black_box(tokens);
}
})
});
group.bench_with_input(BenchmarkId::new("hf_tokenizer", name), text, |b, text| {
b.iter(|| {
// Encode multiple times per iteration to amortize measurement overhead
for _ in 0..ITERATIONS_PER_SAMPLE {
let encoding = hf_tokenizer.encode(black_box(text.clone()), true).unwrap();
let token_ids: Vec<u32> = encoding.get_ids().to_vec();
black_box(token_ids);
}
})
});
}
group.finish();
}
criterion_group!(
benches,
bench_tiktoken,
bench_hf_tokenizer,
bench_comparison,
);
criterion_main!(benches);
现在它太不当人了,贵的要死
其他服务用的好好的,但是就是访问 Gemini 的时候提示:
我们的系统检测到您的计算机网络中存在异常流量。请稍后重新发送请求。为什么会这样?
IP 地址:2a09:bac6:d6f9:197d::28a:8c ≠ 2a09:bac5:a720:197d::28a:8c
时间:2026-03-04T11:17:20Z
网址: https://gemini.google.com/?utm_source=app_launcher&utm_medium=owned&utm_campaign=base_all&authuser=0
前两天就出现过一次,然后提了机场工单,让我换家宽出口,好了两天,今天下午又出现了
而且前两天出现后第二天账号就被封了,我申诉回来了,今天下午又这样了
有啥解决办法没有?或者还是机场的问题?有没有不出这个问题的机场啊?