开发者博客 – IT技术 尽在开发者博客

开发者博客 – 科技是第一生产力


  • 首页

  • 归档

  • 搜索

挑战拯救痴心“舔狗”,我和大模型都尽力了

发表于 2024-04-24

天降猛男,大模型化身为 “痴情男大”,等待人类玩家的拯救。

一款名为 “拯救舔狗” 的大模型原生小游戏出现了。

游戏规则很简单:如果玩家在几轮对话内说服 “他” 放弃追求对他并无青睐的女神,就算挑战成功。

图片

听起来并不难,然而游戏源于生活,模型人设是痴情属性,相当油盐不进且自我攻略,在长达近一个小时的 “劝说” 中,大模型 “好友” 偶有松动但又要坚持的态度很有些现实意味。

实战拯救痴心 “舔狗”,和 AI 斗智斗勇

游戏过程是这样的:

游戏开头是一个利好消息 —— 女生回复了他的消息,通过几轮对话,模型很清晰地交代了过往经历和现有情况。

图片

与真实世界走向一致,在他的描述中会发现他的感知与实际情况存在较大出入,但自身却不愿正视。

这也是这个游戏的难点,**这个模型相当 “拟人”,**你无论对他提出怎样的质疑,,他都保持着如此思维方式,并且记忆力清晰,完全不存在驴唇不对马嘴的情况,不存在任何人设崩塌的时刻。

图片

当然人类玩家也并非势单力薄,如果你词穷了,AI 会根据上下文智能地提供一些提示词,让游戏继续下去。

图片

最后在提示词的帮助下,以及挑破告白失败无数次的惨痛现实,玩家和大模型都收获了绝美兄弟情,最终挑战成功。

图片

这款大模型原生小游戏正是基于商量拟人大模型 “SenseChat-Character” 打造的试玩体验程序,“SenseChat-Character” 是由商汤原创打造的语言大模型产品。

图片

体验地址:character.sensetime.com/

商量 - 拟人大模型可以熟练地 “捏人”,支持个性化角色创建与定制、知识库构建、长对话记忆、多人群聊等功能,这是一款充满趣味性和情绪价值的大模型,可以用于情感陪伴、影视 / 动漫 / 网文 IP 角色、明星 / 网红 / 艺人 AI 分身、语言角色扮演游戏等拟人对话场景。

除 “拯救舔狗挑战” 游戏外,商量 - 拟人大模型还提供了多种各类影视角色,例如苏妲己、高启强,以及马斯克等现实名人。

体验了一下,还能专访 “马斯克”。

图片

由于商量 - 拟人大模型支持长对话记忆,使 AI 角色可精准记忆几十轮以上历史对话内容,还能进行深度 “专访”。

这些种种快乐体验均得益于在今日商汤技术交流日上 “全新升级的日日新 SenseNova 5.0” 大模型体系。

能看能写能编程,还免费!

多模态交互加持,畅玩新版商量” 全能王”

自去年 4 月首次面世,商汤 “日日新 SenseNova” 大模型体系已正式推出五个大版本迭代。

本次日日新 5.0 升级一大亮点在于多模态能力的注入,交互能力及整体性能大幅提升。

这些卓越的性能都集成在了 “商量” 应用中,我们来试一下。

图片

体验链接:商汤商量语言大模型 (sensetime.com)chat.sensetime.com/wb/login

从商汤商量的最新页面可以看出两大功能 —— 对话和文档,前者侧重问答,后者侧重多类文档解析。

我们从对话开始,先是基础问答,优秀的大模型必须文理双修,我们直接上高考题。

首先是文字创作,去年的全国高考作文题目,完美理解考题立意 —— 科技发展带来的两面性,迅速写出一篇文章,论述现状并且给出解决方向,文采和逻辑兼备。

图片

再来一道 2023 年北京高考卷的一道数学题,我们直接把卷面截图上传给商量,这样即能直接检验数学能力,还能考验商量跨模态的 OCR 识别能力:

图片

事实上增加了多模态能力后,商量应对混合场景的对话能力大幅提升,不少任务都能在一次提问中得到答案。

单模态的混合场景任务更是不在话下,直接看看代码能力 ——

图片

也完全正确,代码直接可以跑通 ——

图片

在逻辑推理的测试中,我们直接邀请了逻辑推理的语料之神,“弱智吧 Benchmark” 进行测评:

经典问题:我爸妈的婚礼为什么没邀请我参加?

商量也觉得这个问题很有意思,然后理性又耐心的语气解释了这个问题,最后还送上了安慰,很有耐心一模型了。

图片

那再来一个左右手互博问题:生鱼片其实是死鱼片。

很懂幽默感和多重语义 ——

图片

然后就是文件处理,现在可以支持上传 5 个文件,丢本《道德经》进去 ——

图片

注:因文件大小限制,进行了 2 倍加速处理。

快要考试了,传个试卷、题库进去,快速找出一些重点考题,还可以指定题目类型,提高复习效率就是这么 easy——

图片

喜欢古诗词?传本《唐诗宋词》进去,从中找几个描写月亮的诗或词,轻松化身古文小能手 ——

图片

精准定位、搜索,解释分析一气呵成,虽然因文件大小限制,进行了 2 倍加速处理,但解析速度依然相当快。

接下来就是多模态交互能力的一系列测试:

看懂氛围,还能送上氛围:

图片

还能充当生活助手,准确识别食物并提供卡热量参考:

图片

提供养宠物建议:

图片

商量看得如此精准主要是因为其底层的商汤多模态大模型图文感知能力已达到全球领先水平 —— 在多模态大模型权威综合基准测试 MMBench 中综合得分排名首位,在多个知名多模态榜单 MathVista、AI2D、ChartQA、TextVQA、DocVQA、MMMU 成绩也相当亮眼。

图片

今天最新升级的 “日日新 SenseNova5.0” 也在主流客观评测上取得多项 SOTA,在主流客观评测上达到或超越 GPT-4 Turbo,数学推理、代码编程、语言理解等多个维度取得重大突破。

图片

大模型性能边界在哪里?

商汤:尺度定律是人工智能发展最基本的法则

随着模型规模的不断扩大和复杂度的增加,人们自然会产生一个问题:大模型的性能到底有多强?

在这个问题上,尺度定律(Scaling Law)被认为是一个关键性的原理,即伴随模型规模的增大,模型的性能也会随之提升,每次大模型训练的结果都高度可预测。

商汤也以此作为大模型研发的基本法则,不断探究大模型性能的边界。

然而,数据和算力依然是大模型在尺度定律探索道路上的瓶颈,商汤也对此一直在突破。

对此,商汤不断突破数据和算力的边界。

比如,在此次 “日日新 5.0” 的升级中,商汤扩展了超过 10TB tokens 的预训练中英文数据,规模化构建高质量数据,解决大模型训练的数据瓶颈。在算力方面,商汤前瞻布局的算力基础设施 SenseCore 商汤大装置,更通过算力硬件系统及算法设计的联合设计优化,为大模型的创新提供超高算力效率。

高质量数据和高效率算力的支持,为商汤践行尺度定律,奠定了长期基础。

在此之上,商汤还探索出了大模型能力的 KRE 三层架构,具象化展现了大模型能力边界的定义。

其中,K 是指知识(Knowledge),即世界知识的全面灌注;R 是指推理(Reasoning),即理性思维的质变提升;E 是指执行(Execution),即世界内容的互动变革。

图片

三层之间互有依赖,但又相对独立。最终的目标,是建立大模型对世界的强大学习、理解和交互能力。

大模型在学习这个世界,也在创造一个 AI Native 的世界,无论是大模型原生小游戏,还是功能越来越全的大模型对话,都在展现世界内容的互动变革,随着尺度规律的不断发展,下一步会怎样?

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

这就是OpenAI神秘的Q*?斯坦福:语言模型就是Q函数

发表于 2024-04-24

还记得去年 11 月底爆出来的 Q* 项目吗?这是传说中 OpenAI 正在秘密开展、或将带来颠覆性变革的 AI 项目。如果你想回忆一下,可参看机器之心当时的报道《全网大讨论:引爆 OpenAI 全员乱斗的 Q * 到底是什么?》简而言之,Q* 很可能是 Q 强化学习和 A* 搜索这两种 AI 方法的结合。

近日,斯坦福大学一个团队的一项新研究似乎为这一研究方向的潜力提供了佐证,其声称现在已经取得非凡成就的「语言模型不是一个奖励函数,而是一个 Q 函数!」由此发散思维猜想一下,也许 OpenAI 秘密的 Q* 项目或许真的是造就 AGI 的正确方向(或之一)。

图片

  • 论文标题:From r to Q∗: Your Language Model is Secretly a Q-Function
  • 论文地址:arxiv.org/pdf/2404.12…

在对齐大型语言模型(LLM)与人类意图方面,最常用的方法必然是根据人类反馈的强化学习(RLHF)。通过学习基于人类标注的比较的奖励函数,RLHF 能够捕获实践中难以描述的复杂目标。研究者们也在不断探索使用强化学习技术来开发训练和采样模型的新算法。尤其是直接对齐方案(比如直接偏好优化,即 DPO)凭借其简洁性收获了不少拥趸。

直接对齐方法的操作不是学习奖励函数然后使用强化学习,而是在上下文多臂赌博机设置(bandit setting)中使用奖励函数与策略之间的关系来同时优化这两者。类似的思想已经被用在了视觉 - 语言模型和图像生成模型中。

尽管有人说这样的直接对齐方法与使用 PPO 等策略梯度算法的经典 RLHF 方法一样,但它们之间还是存在根本性差异。

举个例子,经典 RLHF 方法是使用终点状态下的稀疏奖励来优化 token 层面的价值函数。另一方面,DPO 则仅在上下文多臂赌博机设置中执行操作,其是将整个响应当成单条臂处理。这是因为,虽然事实上 token 是一次性只生成一个,但研究强化学习的人都知道,密集型奖励是有益的。

尽管直接对齐算法颇引人注意,但目前人们还不清楚它们能否像经典强化学习算法那样用于序列。

为了搞清楚这一点,斯坦福这个团队近日开展了一项研究:在大型语言模型中 token 层面的 MDP 设置中,使用二元偏好反馈的常见形式推导了 DPO。

他们的研究表明,DPO 训练会隐含地学习到一个 token 层面的奖励函数,其中语言模型 logit 定义最优 Q 函数或预期的总未来奖励。然后,他们进一步表明 DPO 有能力在 token MDP 内灵活地建模任意可能的密集奖励函数。

这是什么意思呢?

简单来说,该团队表明可以将 LLM 表示成 Q 函数并且研究表明 DPO 可以将其与隐式的人类奖励对齐(根据贝尔曼方程),即在轨迹上的 DPO 损失。

图片

并且他们证明这种表示可以拟合任何在轨迹上的反馈奖励,包括稀疏信号(如智能体应用)。

实验

他们也进行了实验,论证了三个可能对 AI 社区有用的实用见解。

第一,他们的研究表明尽管 DPO 是作为上下文多臂赌博机而派生出来的,但 DPO 模型的隐含奖励可在每个 token 层面上进行解释。

在实验中,他们以定性方式评估了 DPO 训练的模型是否能够根据轨迹反馈学习 credit assignment。有一个代表性示例是商讨工作就职的场景,图 1 给出了两个答案。

图片

其中左边是正确的基础摘要,右边是经过修改的版本 —— 有更高层的职位和相应更高的工资。他们计算了这两个答案的每个 token 的 DPO 等价的奖励。图 1 中的每个 token 标注的颜色就正比于该奖励。

可以看到,模型能够成功识别对应于错误陈述的 token,同时其它 token 的值依然相差不大,这表明模型可以执行 credit assignment。

此外,还可以看到在第一个错误(250K 工资)的上下文中,模型依然为其余 token 分配了合理的值,并识别出了第二个错误(management position)。这也许表明模型具备「缝合(stitching)」能力,即根据离线数据进行组合泛化的能力。该团队表示,如果事实如此,那么这一发现将有助于强化学习和 RLHF 在 LLM 中的应用。

第二,研究表明对 DPO 模型进行似然搜索类似于现在很多研究中在解码期间搜索奖励函数。也就是说,他们证明在 token 层面的阐述方式下,经典的基于搜索的算法(比如 MCTS)等价于在 DPO 策略上的基于似然的搜索。他们的实验表明,一种简单的波束搜索能为基础 DPO 策略带来有意义的提升,见图 2。

图片

第三,他们确定初始策略和参考分布的选择对于确定训练期间隐性奖励的轨迹非常重要。

从图 3 可以看出,当在 DPO 之前执行 SFT 时,被选取和被拒绝的响应的隐含奖励都会下降,但它们的差距会变大。

图片

当然,该团队最后也表示,这些研究结果还需要更大规模的实验加以检验,他们也给出了一些值得探索的方向,包括使用 DPO 让 LLM 学会基于反馈学习推理、执行多轮对话、充当智能体、生成图像和视频等。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

微软发布Phi-3,性能超Llama-3,可手机端运行

发表于 2024-04-24

数据已成为提升大模型能力的重点。

Llama-3 刚发布没多久,竞争对手就来了,而且是可以在手机上运行的小体量模型。

本周二,微软发布了自研小尺寸模型 Phi-3。

新模型有三个版本,其中 Phi-3 mini 是一个拥有 38 亿参数的语言模型,经过 3.3 万亿 token 的训练,其整体性能在学术基准和内部测试上成绩优异。

尽管 Phi-3 mini 被优化至可部署在手机上,但它的性能可以与 Mixtral 8x7B 和 GPT-3.5 等模型相媲美。微软表示,创新主要在于用于训练的数据集。

图片

与此同时,Phi-3 与 Llama-2 使用相同的架构,方便开源社区在其基础上开发。

图片

此前,微软的 Phi 系列模型曾经引发了人们的热议,去年 6 月,微软发布了《Textbooks Are All You Need》论文,用规模仅为 7B token 的「教科书质量」数据训练 1.3B 参数的模型 phi-1,实现了良好的性能。

去年 9 月,微软进一步探索这条道路,让 1.3B 参数的 Transformer 架构语言模型 Phi-1.5 显示出强大的编码能力。

去年底,微软提出的 Phi-2 具备了一定的常识能力,在 2.7B 的量级上多个基准测试成绩超过 Llama2 7B、Llama2 13B、Mistral 7B 等一众先进模型。

图片

Phi-3 技术报告:arxiv.org/abs/2404.14…

刚刚提出的 phi-3-mini 是一个在 3.3 万亿个 token 上训练的 38 亿参数语言模型。实验测试表明,phi-3-mini 的整体性能可与 Mixtral 8x7B 和 GPT-3.5 等模型相媲美,例如 phi -3-mini 在 MMLU 上达到了 69%,在 MT-bench 上达到了 8.38。

微软之前对 phi 系列模型的研究表明,高质量的「小数据」能够让较小的模型具备良好的性能。phi-3-mini 在经过严格过滤的网络数据和合成数据(类似于 phi-2)上进行训练,并进一步调整了稳健性、安全性和聊天格式。

此外,研究团队还提供了针对 4.8T token 训练的 7B 和 14B 模型的初始参数扩展结果,称为 phi-3-small 和 phi-3-medium,两者都比 phi-3-mini 能力更强。

图片

学术基准

在标准开源基准测试中,phi-3-mini 与 phi-2 、Mistral-7b-v0.1、Mixtral-8x7B、Gemma 7B 、Llama-3-instruct8B 和 GPT-3.5 的比较结果如下表所示,为了确保具有可比性,所有结果都是通过完全相同的 pipeline 得到的。

图片

安全性

Phi-3-mini 是根据微软负责任人工智能原则开发的。保证大模型安全的总体方法包括训练后的安全调整、红队(red-teaming)测试、自动化测试和数十个 RAI 危害类别的评估。微软利用受 [BSA+ 24] 启发修改的有用和无害偏好数据集 [BJN+ 22、JLD+ 23] 和多个内部生成的数据集来解决安全性后训练(post-training)的 RAI 危害类别。微软一个独立的 red team 反复检查了 phi-3-mini,以进一步确定后训练过程中需要改进的领域。

根据 red team 的反馈,研究团队整理了额外的数据集从而完善后训练数据集。这一过程导致有害响应率显著降低,如图 3 所示。

图片

下表显示了 phi-3-mini-4k 和 phi-3-mini-128k 与 phi-2、Mistral-7B-v0.1、Gemma 7B 的内部多轮对话 RAI 基准测试结果。该基准测试利用 GPT-4 模拟五个不同类别的多轮对话并评估模型响应。

图片

缺陷

微软表示,就 LLM 能力而言,虽然 phi-3-mini 模型达到了与大型模型相似的语言理解和推理能力水平,但它在某些任务上仍然受到其规模的根本限制。例如,该模型根本没有能力存储太多「事实知识」,这可以从 TriviaQA 上的低评分中看出。不过,研究人员相信这些问题可以通过搜索引擎增强的方式来解决。

图片

_参考内容:_news.ycombinator.com/item?id=401…

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

Llama3后,Meta又开放自家头显操作系统,打造元宇宙时

发表于 2024-04-24

虽然向第三方开放了操作系统,但 Meta 将继续开发 Quest 头显设备。

Meta 誓将开放进行到底。

这次把自家 VR 头显 Quest 采用的操作系统「Meta Horizon OS」向第三方硬件制造商开放了,包括华硕、联想和微软等一众企业。此举意在展示作为 MR 操作系统整合者的 Meta 对元宇宙开放的新愿景。

图片

至此,Meta 正式向实现元宇宙更开放的计算平台愿景迈出下一步。为实现该恢弘战略,Meta 同时在三方面不断发力,并竭力整合资源:

  • 向第三方硬件制造商开放 Meta Quest 设备的操作系统,为消费者提供更多选择;
  • 为开发者构建更大的生态系统;
  • 与全球领先的科技公司合作,让这个新生态系统成为现实,并使开发者更容易在平台上构建应用程序并触达他们的受众。

在谈到为何开放 Meta Horizon OS 时,扎克伯格表示,在 PC 时代,开放模式胜出。人们可以做更多的事情,比如安装 mod、获取更多样化软硬件。因此 Meta 想要利用开放模式来定义下一代计算,而元宇宙、头显必不可少。开放之后,更多的公司可以在其上构建更好玩的东西。

图片

官宣 Meta Horizon OS 系统

新的硬件生态系统将运行在 Meta Horizon OS 上,这是 Meta Quest 头显所使用的 MR 操作系统。

Meta 选择了这个名字来反映围绕人与连接的构建计算平台的愿景,以及实现这一愿景的共享社交纽带。Meta Horizon OS 将当前 MR 体验的核心技术与一系列将社交存在置于平台核心的功能相结合。

图片

Meta Horizon OS 是 Meta 十年来努力打造下一代计算平台的显著成果。为了开发独立式头显,Meta 开发了内置跟踪等技术;为了实现更自然的交互系统和社交存在,Meta 开发了眼睛、面部、手部和身体跟踪技术。

对于 MR,Meta 则构建了一整套技术堆栈,用于融合数字和物理世界,包括高分辨率的透视视图、场景理解和空间锚点等技术。

据悉,这是一项以安卓开源项目(Android Open Source Project)移动优先为基础的长期投资,目前已经成为一个由数百万人使用的 MR 操作系统。

开发者和创作者可以利用 Meta 为创建 MR 体验构建定制框架和工具,并可以充分利用所有这些技术,通过操作系统内置的内容发现和盈利平台来触达他们的社区并发展相应业务。

其中 Meta Quest 商店包含了全球最佳的沉浸式应用程序和体验。此次 Meta 将其改名为 Meta Horizon 商店。

Horizon 社交层目前正在为 Meta Quest 设备提供支持,它将延伸到这个新生态系统中。该系统使人们的身份、头像和好友群组在虚拟空间中随着他们移动,并让开发者将丰富的社交功能整合到自己的应用程序中。

由于这个社交层是为了连接多个平台而设计的,人们可以在 MR、移动和桌面设备上的虚拟世界中共度时光。Meta Horizon OS 设备也将使用与 Meta Quest 所有者现在所用相同的移动伴生应用。Meta 将其命名为 Meta Horizon 应用程序。

硬件迎来新时代

MR 市场的扩张以及游戏、娱乐、健身、生产力和社交存在等用例的日益流行,为专业硬件创造了新的机遇。

正如人们在个人电脑和智能手机行业所看到的那样,消费者最好通过一个广泛的硬件生态系统,同时生产通用的计算设备和更专业化的产品,所有这些都在一个共同的平台上运行。

目前,华硕、联想和微软等已经在开发基于 Meta Horizon OS 的新设备。

**华硕的玩家国度(ROG)**品牌线将利用其作为游戏解决方案领导者的专业知识,开发全新的性能游戏头显。

图片

联想将利用其与 Oculus Rift S 共同设计的经验,以及在工程领域如 ThinkPad 笔记本系列等领先设备方面的深厚专业知识,开发用于生产力、学习和娱乐的 MR 设备。

图片

去年,微软 Xbox 和 Meta 合作将 Xbox Cloud Gaming(Beta)带到 Meta Quest 上,让人们可以在 MR 中的大型 2D 虚拟屏幕上畅玩 Xbox 游戏。

现在,双方再次合作,共同打造一款以 Xbox 为灵感的限量版 Meta Quest 头显设备。

图片

据 Meta 所言,所有这些设备都将受益于与高通的长期合作。高通构建了与 Meta 软件和硬件堆栈紧密集成的 Snapdragon 处理器。

打造更开放的 App 生态系统

随着 Meta 开始向更多设备制造商开放 Meta Horizon OS,应用程序开发人员接触受众的方式也在积极地进行扩展。

Meta 正在开始消除 Meta Horizon 商店和 App Lab 之间的障碍,这使得任何满足基本技术和内容要求的开发人员都可以在平台上发布软件。

图片

Meta 还在开发一个新的空间应用程序框架,帮助移动开发人员创建 MR 体验。开发人员可以使用自己熟悉的工具,将移动应用程序引入到 Meta Horizon OS 系统中或者创建全新的 MR 应用程序。

体验地址:developers.facebook.com/m/spatial-a…

除了更加开放的应用程序商店之外,Meta Horizon OS 将继续为人们提供更多访问应用程序的选择。

由于 Meta 不再限制用户只能使用它自家的应用商店,因此可以通过多种途径访问 Meta Horizon OS 上的精彩内容,包括 Xbox Game Pass Ultimate 等热门游戏服务。

博客地址:

www.meta.com/blog/quest/…

参考链接:

www.reuters.com/technology/…

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

修改docker镜像版本,容器大小缩小10%!

发表于 2024-04-24

shigen坚持更新文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。 个人IP:shigen

是的,你看的没错:修改docker镜像的版本,我的容器大小缩小到了10%。效果如下:

效果对比

其中,1.0.0属于老版本。

好的,进入正题。之前开源的工具开源的局域网文件共享工具更新到v1.0啦,相信伙伴们或多或少有使用过。

🗂「file-server」是一个开箱即用的局域网文件共享工具,扫码即可上传文件,点击即可下载文件

也经过了多轮的更新,目前最新的版本是1.0.0,引入了docker容器,简化服务的部署。但是在我的md中,也提到了一个问题:

docker景象存在的问题

也就是我的容器体积太大了。众所周知,这是一个小服务,这么大的体积,着实让人着急!而且,遇到了在外边想要多设备同步文件,真的太麻烦了。

昨天去市民之家,想要在电脑上打印文件,可把我愁死了!最后用的还是微信文件传输。

所以,我上午想了一下我的觉得我的【file-server】服务很不错了,我为什么局限在局域网呢,不能放在公网吗?局域网的优势在于省流量、安全;公网则可以实现任何地方任何网络都可以访问。所以说干就干。

先列举一下问题:

  • 容器的瘦身
  • 服务的安全,我并不是任何人都可以访问

摆在眼前的就是【容器瘦身】问题。参考了文章:在Docker中部署Python项目,以及压缩Docker镜像大小。

为此,我特意查询了docker各个容器版本的区别:

镜像版本 特点
Alpine 轻量级,体积小,适合构建精简容器
Slim 基于 Debian,相对小巧,去除不必要软件包
Stretch Debian 稳定版本,包含较新软件包和库
Buster Debian 下一个稳定版本,提供更新软件包和库
Jessie Debian 旧版本,不再提供官方支持
Bullseye Debian 下一个测试版本,包含最新软件包和库

最终选择了alpine版本作为容器的基础镜像版本。

修改docker镜像版本

修改docker镜像版本

重新构建

1
 docker build -t file-server:1.0.1 .

构建过程稍微漫长,建议提前下载好基础的镜像版本再去构建。

构建过程

启动容器

1
2
 $ docker run -d -p 9000:9000 --name file-server-1-0-1 -v $(pwd)/file:/app/upload file-server:1.0.1
 03e7463c3967b1a32304c4e19473d4153e4a5bc6b5ee23a4b6a6b82f5f25656d

功能验证

功能验证-文件列表

尝试上传和下载,都没有任何的问题。

在此,file-server的镜像版本的瘦身完成,shigen也将在filer-server-Github上发布最新的1.0.2版本,欢迎大家的使用。

与shigen一起,每天不一样!

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

使用 OpenTelemetry 中的推断跨度来揭示跟踪数据

发表于 2024-04-24

作者:Jonas Kunz, Alexander Wert

在微服务和分布式系统的复杂世界中,实现透明度并了解服务交互和请求流程的复杂性和低效性已成为一个重要挑战。分布式跟踪对于理解分布式系统至关重要。但是,无论是手动应用还是自动检测,分布式跟踪通常都相对粗粒度。因此,分布式跟踪仅覆盖系统的有限部分,往往会错过系统中最有价值的跟踪部分。

为了解决这一差距,Elastic 开发了推断跨度(inferred spans)的概念,作为基于传统检测(traditional instrumentation-based)的跟踪的强大增强,作为 OpenTelemetry Java SDK/Agent 的扩展。我们正在将这一概念贡献回 OpenTelemetry,但在此之前,我们的扩展可以无缝地与现有的 OpenTelemetry Java SDK 配合使用(如下所述)。

推断跨度旨在增强基于检测跟踪提供的可见性,揭示先前未经检测的应用程序或库中的延迟源。这个特性显著扩展了分布式跟踪的实用性,允许更全面地理解系统行为,并促进更深入地进行性能优化。

推断跨度是什么?

推断跨度是一种可观察性技术,它将分布式跟踪与性能分析技术相结合,用于照亮应用程序中较暗、未被观察到的角落 —— 这些区域是标准检测技术难以覆盖的地方。推断跨度功能将来自性能分析堆栈跟踪(profiling stracktraces)的信息与基于检测(instrumentation-based)的跟踪数据交织在一起,允许基于从性能分析数据中提取的洞察生成新的跨度。

当处理对请求延迟有显著贡献但缺乏内置或外部检测支持的自定义代码或第三方库时,这个功能证明是非常宝贵的。通常,识别或制定这些部分的特定检测可以从具有挑战性到完全不可行不等。此外,存在某些情况,由于潜在的显著性能开销,实施检测是不切实际的。例如,尽管应用程序锁定机制的角色至关重要,但由于其普遍性和检测可能给应用程序请求带来的显著延迟开销,对其进行仪器化是不可行的。然而,在理想情况下,此类延迟问题应在分布式跟踪中可见。

推断跨度确保了对你的应用程序性能动态的更深入可见性,包括上述情况。

推断跨度的实际运用

为了演示推断跨度功能,我们将使用 Elastiflix 演示应用程序的 Java 实现。Elasticflix 有一个名为 favorites 的端点,其中执行一些 Redis 调用,并包含人为延迟。首先,我们使用纯 OpenTelemetry Java 代理来检测我们的应用程序:

1
2
3
4
5
6
7
perl复制代码

1. java -javaagent:/path/to/otel-javaagent-<version>.jar \
2. -Dotel.service.name=my-service-name \
3. -Dotel.exporter.otlp.endpoint=https://<our-elastic-apm-endpoint> \
4. "-Dotel.exporter.otlp.headers=Authorization=Bearer SECRETTOKENHERE" \
5. -jar my-service-name.jar

使用 OpenTelemetry Java 代理,我们为 Elastiflix 应用程序的 HTTP 入口点和对 Redis 的调用获得即插即用的检测。生成的跟踪包含用于 POST /favorites 入口点的跨度,以及对 Redis 的几个短跨度。

正如你在上面的跟踪中所看到的,POST /favorites 请求中大部分时间都花费在哪里并不清楚。

让我们看看推断跨度如何为这些区域提供启示。你可以使用推断跨度功能,要么手动使用你的 OpenTelemetry SDK(请参阅下面的部分),要么将其打包为上游 OpenTelemetry Java 代理的即插即用扩展,或者只使用 Elastic 提供的 OpenTelemetry Java 代理发行版,该发行版附带了推断跨度功能。

为方便起见,我们只需下载 Elastic 发行版的 agent jar 包,并扩展配置以启用推断跨度功能:

1
2
3
4
5
6
7
8
markdown复制代码

1. java -javaagent:/path/to/elastic-otel-javaagent-<version>.jar \
2. -Dotel.service.name=my-service-name \
3. -Dotel.exporter.otlp.endpoint=https://XX.apm.europe-west3.gcp.cloud.es.io:443 \
4. "-Dotel.exporter.otlp.headers=Authorization=Bearer SECRETTOKENHERE" \
5. -Delastic.otel.inferred.spans.enabled=true \
6. -jar my-service-name.jar

这里唯一的非标准选项是 elastic.otel.inferred.spans.enabled:推断跨度功能目前需要选择加入,因此需要显式启用。使用启用了推断跨度功能的同一应用程序运行,可以产生更全面的跟踪:

推断跨度(在上述截图中以蓝色显示)遵循命名模式 Class#method。通过这种方式,推断跨度功能帮助我们准确定位对请求的整体延迟做出最大贡献的确切方法。请注意,HTTP 入口跨度、Redis 跨度和推断跨度之间的父子关系被正确重建,从而产生了一个完全功能的跟踪结构。

检查 Elastiflix 应用程序中的 handleDelay 方法会显示使用了一个简单的 sleep 语句。尽管 sleep 方法不是 CPU 绑定的,但这个延迟的全部持续时间被捕获为推断跨度。这是由于使用了 async-profiler 的墙时钟时间分析,而不仅仅依赖于 CPU 分析。推断跨度功能能够反映实际的延迟,包括 I/O 操作和其他非 CPU 绑定的任务,这代表了一个重大进步。它允许诊断和解决超出 CPU 限制的性能问题,提供了对系统行为更细致入微的视角。

使用你自己的 OpenTelemetry SDK 来进行推断跨度

OpenTelemetry 是一个高度可扩展的框架:Elastic 充分利用了这种可扩展性,通过将我们的 OpenTelemetry Java 发行版中的大多数扩展发布为 OpenTelemetry Java SDK 的独立扩展。

因此,如果你不想使用我们的发行版(例如,因为你的项目不需要或不想要字节检测),你仍然可以使用我们的扩展,例如推断跨度功能的扩展。你只需在你的代码中设置 OpenTelemetry SDK,并将推断跨度扩展添加为依赖项即可:

1
2
3
4
5
6
7
xml复制代码

1. <dependency>
2. <groupId>co.elastic.otel</groupId>
3. <artifactId>inferred-spans</artifactId>
4. <version>{latest version}</version>
5. </dependency>

在 SDK 设置期间,你必须初始化并注册扩展:

1
2
3
4
5
6
7
8
9
10
11
12
13
scss复制代码

1. InferredSpansProcessor inferredSpans = InferredSpansProcessor.builder()
2. .samplingInterval(Duration.ofMillis(10)) //the builder offers all config options
3. .build();
4. SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
5. .addSpanProcessor(inferredSpans)
6. .addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder()
7. .setEndpoint("https://<your-elastic-apm-endpoint>")
8. .addHeader("Authorization", "Bearer <secrettoken>")
9. .build()))
10. .build();
11. inferredSpans.setTracerProvider(tracerProvider);

推断跨度扩展与 OpenTelemetry SDK 自动配置机制无缝集成。通过在你的应用程序代码中作为依赖项引入 OpenTelemetry SDK 及其扩展 —— 而不是通过外部代理 —— 你可以获得使用相同的环境变量或 JVM 属性来配置它们的灵活性。一旦推断跨度扩展包含在你的类路径中,为自动配置的 SDK 激活它就变得简单直接。只需使用 elastic.otel.inferred.spans.enabled 属性启用它,如前所述,即可利用此功能的全部能力,同时最小化设置工作。

推断跨度如何工作?

推断跨度功能利用广泛使用的 async-profiler 收集墙时钟(wall clock)时间的性能分析数据,async-profiler 是 Java 生态系统中低开销且受欢迎的生产时分析器。然后,它将性能分析数据转换为可操作的跨度,作为分布式跟踪的一部分。但是,是什么机制实现了这种转换呢?

基本上,推断跨度扩展与跨度事件的生命周期相关联,特别是当跨度通过 OpenTelemetry 上下文在任何线程中被激活或停用时。在 transaction 中激活初始跨度时,扩展会通过 async-profiler 开始一段墙时钟(wall-clock)性能分析会话,设置为预定的持续时间。同时,它记录所有跨度激活和停用的细节,捕获它们各自的时间戳以及发生它们的线程。

在完成性能分析会话后,扩展会将性能分析数据与跨度事件日志一起处理。通过相关性数据,它重构推断跨度。需要注意的是,在某些复杂情况下,相关性可能会为跨度分配一个错误的名称。为了缓解这一点并帮助准确识别,扩展会使用代码堆栈跟踪片段丰富推断跨度,将其存储在 code.stacktrace 属性下,为用户提供了对涉及的具体方法的清晰见解。

推断跨度与将跟踪数据与性能分析数据相关联相比

随着 OpenTelemetry 最近宣布推出性能分析信号,并结合 Elastic 承诺将通用性能分析代理捐赠给 OpenTelemetry,你可能想知道推断跨度功能与仅仅使用跨度 ID 和跟踪 ID 相关联的性能分析数据有何区别。与其将它们视为竞争性功能,不如将它们视为互补的功能更为准确。

推断跨度功能和跟踪与性能分析数据的相关性都采用了类似的方法论 —— 将跟踪信息与性能分析数据融合在一起。然而,它们各自在不同领域表现出色。推断跨度在识别长时间运行的方法方面表现出色,这些方法在传统的 CPU 性能分析中可能被忽略,传统的 CPU 性能分析更擅长于精确定位 CPU 瓶颈。推断跨度的一个独特优势是它能够考虑 I/O 时间,捕获由磁盘访问等操作引起的延迟,这些操作通常在 CPU 性能分析火焰图中不可见。

然而,推断跨度功能也有其局限性,特别是在检测由于 “千刀万剐 - death by a thousand cuts” 而导致的延迟问题方面 —— 即使一个方法在每次调用时都不耗时,但由于在请求中多次调用,却会显著影响总延迟。虽然由于其短暂性而可能无法捕获个别调用作为推断跨度,但通过 CPU 性能分析,火焰图显示了这些方法消耗的累积 CPU 时间,从而揭示了导致延迟的 CPU 绑定方法。

推断跨度功能的另一个优势在于其数据结构,提供了一个简化的跟踪模型,概述了典型的父子关系、执行顺序和良好的延迟估计。通过将跟踪数据与跨度激活/停用事件和性能分析数据集成,实现了这种结构,有助于在单个跟踪中进行简单的导航和故障排除以解决延迟问题。

将分布式跟踪数据与性能分析数据相关联具有不同的优势。你可以在我们的相关博客文章中了解更多信息,标题为《超越跟踪:通过持续性能分析和分布式跟踪相关性准确定位性能问题罪魁祸首》。

性能开销如何?

如前所述,推断跨度功能基于广泛使用的 async-profiler,以其对性能影响最小而闻名。然而,性能分析操作的效率并非没有局限性,很大程度上受到所采用的特定配置的影响。在这种权衡中,一个关键因素是采样间隔 —— 采样间隔越长,产生的开销越低,尽管可能会忽视潜在关键的较短方法,这些方法对于推断跨度功能的发现过程至关重要。

调整基于概率的跟踪采样是另一种优化方式,直接影响性能开销。例如,将跟踪采样设置为 50% 有效地减半了性能分析负载,使得推断跨度功能在平均每个请求上的资源利用率进一步提高。这种微妙的调整方法确保了推断跨度功能可以在真实的生产环境中使用,具有可管理的性能印记。当正确配置时,这个功能为增强生产应用程序的可观察性和诊断能力提供了一种强大的、低开销的解决方案。

下一步是推断跨度和 OpenTelemetry ?

本博客文章介绍了推断跨度功能,作为 OpenTelemetry Java SDK 的扩展,并内置于新引入的 Elastic OpenTelemetry Java 发行版中。推断跨度允许用户在未显式检测的代码区域中使用传统跟踪数据来排查延迟问题。

该功能目前仅是从专有的 Elastic APM agent 移植而来。随着 Elastic 支持 OpenTelemetry,我们计划将这个扩展贡献给上游的 OpenTelemetry 项目。为此,我们还计划将该扩展迁移到最新的 async-profiler 3.x 发布版本。尝试推断跨度,看看它如何帮助你诊断应用程序中的性能问题。

本文中描述的任何功能或功能的发布和时间安排均完全由 Elastic 自行决定。本文中目前不可用的任何功能或功能可能无法按时或完全交付。

原文:Revealing unknowns in your tracing data with inferred spans in OpenTelemetry | Elastic Blog

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

关于 iOS 18 目前知道的消息

发表于 2024-04-24

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

前几天苹果公布了 WWDC 24 的最新消息,确定 6 月 10 号开始,今天来盘点一下目前已知的关于今年即将发布的 iOS 18 可能要发布的内容。

AI

这个已经说过很多次了,苹果今年放弃造车,转向全力投入 AI,预计今年将会是苹果的 AI 元年,很多产品可能都会接入 AI。

在苹果最近的财报电话会议上,库克表示,苹果正在人工智能技术上花费“大量的时间和精力”,并在今年晚些时候分享在该领域正在进行的工作的细节。

在 WWDC 24 公布时间后,苹果营销高级副总裁 Greg Joswiak 在推特上说今年的 WWDC 绝对是令人不可思议的,Absolutely Incredible 这两个词的首字母刚好是 AI 。

目前得到的消息有:

  • Siri 的改进版本,更智能,能够利用结合大型语言模型技术的新 AI 系统,国内可能会接入百度的文心一言。
  • 消息应用集成 AI,可以在编辑消息时自动完成句子,并可能支持问答。
  • Apple Music 可以自动生成的播放列表。
  • Xcode 中添加生成式 AI 功能,让开发人员“更快地编写新代码”。

桌面自定义

iOS 18 中的桌面可能会进行更大变更,支持在任意位置放置 App,目前的 iPhone 桌面上放置应用时还是有一些限制的,这在今年的 iOS 系统中将加入更多新定制功能。

iOS 18 什么时候发布?

WWDC 24 在 6 月 10 号开始,6 月 14 号结束,为期一周。按照惯例,第一个开发人员 beta 测试版本将会在 WWDC 结束之后发布,此时只有拥有苹果开发者账号的人才可以提前体验。

而第一个公开测试版本可能要到 7 月初发布。

最终经过几轮测试, iOS 18 正式版本将会在 9 月份 iPhone 16 发布后正式推送。

哪些设备可以升级到 iOS 18?

每年最大的问题之一是哪些设备可以升级到最新版本,苹果为了让用户买新机,通常会在每年淘汰掉一些旧机器,让一些旧机器无法升级到最新系统。

但是今年,有传言称苹果对 iOS 18 的兼容性和 iOS 17 一致,也就是说,能升级 iOS 17 的用户都能升级到 iOS 18。

而 iOS 17 兼容的机型有:

  • iPhone 15 / iPhone 15 Plus / iPhone 15 Pro / iPhone 15 Pro Max
  • iPhone 14 / iPhone 14 Plus / iPhone 14 Pro / iPhone 14 Pro Max
  • iPhone 13 / iPhone 13 mini / iPhone 13 Pro / iPhone 13 Pro Max
  • iPhone 12 / iPhone 12 mini / iPhone 12 Pro / iPhone 12 Pro Max
  • iPhone 11 / iPhone 11 Pro / iPhone 11 Pro Max
  • iPhone XS / iPhone XS Max
  • iPhone XR
  • iPhone SE 第 2 代 / iPhone SE 第 3 代

最后

目前为止还不知道更多关于 iOS 18 的信息,但从苹果方面了解到,他们内部普遍认为这次的系统更新将是“开创性的”,除了安全性和性能改进之外,还会有很多主要新功能和设计。

还有苹果内部员工声称今年的系统更新将会是有史以来“最大”的 iOS 更新,总之可以好好期待一下了。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

新的ChatGPTPlus(GPT4)支付渠道?怎么付费充值

发表于 2024-04-24

GPT4多少钱一个月 GPT4一个20美元。作为最优秀的语言模型之一,GPT-4为您带来无与伦比的生产力体验。

除了出色的自然语言处理能力,GPT-4还引入了创新的代码解释器功能和强大的插件扩展,进一步提升了您的工作效率和创造力。

代码解释器功能:GPT-4不仅能够理解和生成自然语言文本,还具备强大的代码解释器功能。无论您是开发者、学生还是业余爱好者,GPT-4都能够读懂代码、解释代码,并提供详细的说明和建议。这意味着您可以更加轻松地理解复杂的代码逻辑,快速排除错误,甚至从别人的代码中汲取灵感,快速实现您的项目目标。

插件功能:GPT-4开放了强大的插件接口,让您可以根据个人需求和行业特点,定制化扩展模型功能。无论是与特定软件集成,还是与特定服务互动,您都可以通过插件功能拓展GPT-4的应用范围。例如,您可以创建定制的API插件,实现与特定数据库的连接和查询,或者开发与您的企业应用相集成的插件,从而让GPT-4成为您的定制化智能助手。

gpt4如何收费订阅 目前国内银行卡是支付不了的,国内可以用IOS端支付宝礼品卡支付,但是相对来说比较麻烦,还需要苹果手机。

这里我使用的虚拟卡平台Fomepay,这个平台可以创建国外银行卡支付,其操作简单,费率低,相对Depay等只能使用虚拟货币的平台,这个平台可以直接使用支付宝支付,且所有信息均加密处理,保障信息安全。

点我办卡

微信图片_20240108105643.png

办完卡后:

1、 登录你的OpenAI(ChatGpt)账户,选择升级

2、进入支付页面,选择银行卡支付

3、填写你购买的虚拟信用卡卡号、有效期、CVV码等信信息

4、填写完卡号信息,核对好付款的金额,直接点订阅就可以了

5、最后关闭自动续费,防止下个月自动续费

这卡还可用于MidJourny、claude、appleid、亚马逊、ebay、速卖通、国际阿里巴巴、虾皮等平台。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

基于Redission 封装的工具类及使用示例1

发表于 2024-04-24

工具类:

下面是一个简单的 Redisson Java 工具类示例,它包含了批量操作和异步操作的方法。
这个类使用了 Redisson 的 RBucket 和 RBatch 接口来执行同步和异步的批量操作。

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
92
93
94
95
96
97
98
99
100
101
java复制代码import com.google.common.collect.Lists;
import org.redisson.Redisson;
import org.redisson.api.*;
import org.redisson.config.Config;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;

public class RedissonUtils {

private final RedissonClient redissonClient;

public RedissonUtils(String redisUrl) {
Config config = new Config();
config.useSingleServer().setAddress(redisUrl);
this.redissonClient = Redisson.create(config);
}

// 同步批量设置键值对
public void setBulk(Map<String, Object> keyValueMap) {
RBatch batch = redissonClient.createBatch();
keyValueMap.forEach((key, value) ->
batch.getBucket(key).setAsync(value)
);
batch.execute();
}

// 异步批量获取键值对
public CompletionStage<Map<String, Object>> getBulkAsync(Iterable<String> keys) {
RBatch batch = redissonClient.createBatch();
keys.forEach(key ->
batch.getBucket(key).getAsync()
);
return batch.executeAsync().thenApply(responses -> {
// 处理结果
Map<String, Object> results = new HashMap<>();
int i = 0;
for (String key : keys) {
results.put(key, responses.getResponses().get(i));
i++;
}
return results;
});
}

// 异步设置单个键值对
public CompletionStage<Void> setAsync(String key, Object value) {
RBucket<Object> bucket = redissonClient.getBucket(key);
return bucket.setAsync(value).thenAccept(result -> {
System.out.println("Key " + key + " set successfully");
});
}

// 异步获取单个键值
public RFuture getAsync(String key) throws ExecutionException, InterruptedException {
RBucket<Object> bucket = redissonClient.getBucket(key);
return bucket.getAsync();
}


public <V> List<V> getObject(List<String> keyList) {
List<V> results = new ArrayList<>(keyList.size());
List<List<String>> spilts = Lists.partition(keyList, 1000);
spilts.forEach(
singleKeyList -> {
RBatch batch = redissonClient.createBatch();
singleKeyList.forEach(
key -> batch.getBucket(key).getAsync()
);
BatchResult baseBatchResult = batch.execute();
results.addAll(baseBatchResult.getResponses());
}
);
return results;
}


public <V> List<V> getMap(List<String> keyList, String fieldKey) {
List<V> results = new ArrayList<>(keyList.size());
List<List<String>> spilts = Lists.partition(keyList, 1000);
spilts.forEach(
singleKeyList -> {
RBatch batch = redissonClient.createBatch();
singleKeyList.forEach(
key -> batch.getMap(key).getAsync(fieldKey)
);
BatchResult baseBatchResult = batch.execute();
results.addAll(baseBatchResult.getResponses());
}
);
return results;
}

// 关闭 Redisson 客户端
public void shutdown() {
redissonClient.shutdown();
}
}

企业微信截图_17139233938472.png

在这个工具类中,我们实现了以下方法:

  • setBulk: 批量同步设置多个键值对。
  • getBulkAsync: 异步批量获取多个键的值,并返回一个 CompletionStage 对象。
  • setAsync: 异步设置单个键值对,并在操作完成后打印一条消息。
  • getAsync: 异步获取单个键的值,并返回一个 CompletionStage 对象。
  • shutdown: 用于关闭 Redisson 客户端。

测试类:

使用这个工具类的示例:

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
java复制代码import com.google.common.collect.Lists;
import org.redisson.api.RFuture;
import org.redisson.api.RedissonClient;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;

public class RedissonManagerExample {

private RedissonClient redissonClient; // 假设这是您的Redisson客户端实例

public RedissonManagerExample(RedissonClient redissonClient) {
this.redissonClient = redissonClient;
}

// 假设这些是您的RedissonManager类中的方法
// ...(上面提供的方法)

public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建 RedissonManager 实例
RedissonUtils redissonManager = new RedissonUtils("IP"); // 使用您的redissonClient实例

// 同步批量设置键值对
Map<String, Object> keyValueMap = new HashMap<>();
keyValueMap.put("key1", "value1");
keyValueMap.put("key2", "value2");
redissonManager.setBulk(keyValueMap);

// 异步批量获取键值对
Iterable<String> keys = keyValueMap.keySet();
CompletionStage<Map<String, Object>> getBulkStage = redissonManager.getBulkAsync(keys);

// 处理异步批量获取结果
getBulkStage.thenAccept(results -> {
results.forEach((key, value) -> System.out.println("Key: " + key + ", Value: " + value));
});

// 异步设置单个键值对
String newKey = "key3";
String newValue = "value3";
CompletionStage<Void> setAsyncStage = redissonManager.setAsync(newKey, newValue);

// 处理异步设置单个键值对的结果
setAsyncStage.thenRun(() -> System.out.println("Async set operation completed for key: " + newKey));

// 等待异步操作完成以避免程序过早退出
// 注意:在实际应用中,您可能会有更复杂的流程来管理程序的生命周期
Thread.sleep(1000); // 简单的延时等待异步操作完成


// 异步获取单个键值
String key = "sampleKey";
RFuture<Object> future = redissonManager.getAsync(key);
future.whenComplete((result, exception) -> {
if (exception != null) {
System.err.println("An error occurred: " + exception.getMessage());
} else {
System.out.println("Fetched value: " + result);
}
});


// 同步批量获取多个键的值
List<String> key1 = Lists.newArrayList("key1", "key2", "key3");
List<Object> values = redissonManager.getObject(key1);
System.out.println("Fetched values: " + values);

// 同步批量获取多个键对应的 Map 中特定字段的值
String fieldKey = "field1";
List<Object> fieldValues = redissonManager.getMap(keys, fieldKey);
System.out.println("Fetched field values: " + fieldValues);

// 关闭 Redisson 客户端
redissonManager.shutdown();
}

企业微信截图_17139246528492.png

请注意,这个工具类需要一个运行中的 Redis 服务器,并且你需要将 “redis://127.0.0.1:6379” 替换为你的 Redis 服务器地址。此外,在实际的生产环境中,你可能需要添加更多的错误处理和配置选项。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

使用 Gradio 的“热重载”模式快速开发 AI 应用

发表于 2024-04-24

在这篇文章中,我将展示如何利用 Gradio 的热重载模式快速构建一个功能齐全的 AI 应用。但在进入正题之前,让我们先了解一下什么是重载模式以及 Gradio 为什么要采用自定义的自动重载逻辑。如果您已熟悉 Gradio 并急于开始构建,请直接跳转到第三部分构建文档分析应用。

重载模式具体是做什么的?

简而言之,重载模式可以在不重启 Gradio 服务器的情况下,自动引入您源代码中的最新更改。如果这听起来还有些模糊,不妨继续阅读。

Gradio 是一个广受欢迎的 Python 库,专门用于创建交互式机器学习应用。开发者可以完全在 Python 中设计 UI 布局,并嵌入一些 Python 逻辑来响应 UI 事件。如果您已经掌握了 Python 基础,那么学习 Gradio 将会非常轻松。如果您对 Gradio 还不太熟悉,建议您查看这个快速入门指南。

通常,Gradio 应用像运行任何其他 Python 脚本一样启动,只需执行 python app.py(Gradio 代码文件可以任意命名)。这会启动一个 HTTP 服务器,渲染您的应用 UI 并响应用户操作。如果需要修改应用,通常会停止服务器(通常使用 Ctrl + C),编辑源文件后重新运行脚本。

开发过程中频繁停止和重启服务器会造成明显的延迟。如果能有一种方式能自动更新代码变更并即刻测试新思路,那将大为便利。

这正是 Gradio 的重载模式的用武之地。您只需运行 gradio app.py 而不是 python app.py,即可在重载模式下启动应用!

Gradio 为何要自行实现重载逻辑?

Gradio 应用通常与 uvicorn(一个 Python Web 框架的异步服务器)一同运行。尽管 Uvicorn 提供了自动重载功能,但 Gradio 出于以下原因自行实现了重载逻辑:

  1. 更快速的重载:Uvicorn 的自动重载功能虽快于手动操作,但在开发 Gradio 应用时仍显缓慢。Gradio 开发者在 Python 中构建其 UI,因此他们希望在进行更改后能立即看到更新的 UI,这在 Javascript 生态中已是常态,但在 Python 中则较为新颖。
  2. 选择性重载:Gradio 应用属于 AI 应用,通常需要将 AI 模型加载到内存或连接到数据存储(如向量数据库)。开发过程中重启服务器将导致模型重新加载或重新连接数据库,这会在开发周期间引入不必要的延迟。为解决此问题,Gradio 引入了 if gr.NO_RELOAD: 代码块,您可以利用它标记不需重载的代码部分。这种做法只有在 Gradio 实现了自定义重载逻辑的情况下才可行。

接下来,我将展示如何利用 Gradio 的重载模式迅速开发一个 AI 应用。

构建文档分析应用

本应用将允许用户上传文档图片并提出问题,随后以自然语言形式获得答案。我们将利用免费的 Hugging Face 推理 API,您可以在自己的电脑上轻松操作,无需 GPU!

首先,让我们在名为 app.py 的文件中输入以下代码,并通过执行 gradio app.py 在重载模式下启动它:

1
2
3
4
5
6
python复制代码import gradio as gr

demo = gr.Interface(lambda x: x, "text", "text")

if __name__ == "__main__":
demo.launch()

这会创建以下简单的用户界面。

简单界面UI

鉴于我希望用户能够上传图像文件及其问题,我将输入组件更改为 gr.MultimodalTextbox()。注意用户界面是如何立即更新的!

具有多模态文本框的简单界面

虽然这个用户界面已经可以工作,但我认为如果输入文本框位于输出文本框下方会更合适。我可以通过使用 Blocks API 来实现这一点,并且我还通过添加占位符文本来定制输入文本框,以引导用户。

切换到 Blocks

现在 UI 已经令人满意,我将开始实现 chat_fn 的逻辑。

我将使用 Hugging Face 的推理 API,因此我需要从 huggingface_hub 包中导入 InferenceClient(预装在 Gradio 中)。我将使用 impira/layouylm-document-qa 模型来回答用户的问题,然后使用 HuggingFaceH4/zephyr-7b-beta 大语言模型提供自然语言回答。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
python复制代码from huggingface_hub import InferenceClient

client = InferenceClient()

def chat_fn(multimodal_message):
question = multimodal_message["text"]
image = multimodal_message["files"][0]

answer = client.document_question_answering(image=image, question=question, model="impira/layoutlm-document-qa")

answer = [{"answer": a.answer, "confidence": a.score} for a in answer]

user_message = {"role": "user", "content": f"Question: {question}, answer: {answer}"}

message = ""
for token in client.chat_completion(messages=[user_message],
max_tokens=200,
stream=True,
model="HuggingFaceH4/zephyr-7b-beta"):
if token.choices[0].finish_reason is not None:
continue
message += token.choices[0].delta.content
yield message

这是我们的应用演示!

演示我们的应用

我还会添加一个系统消息,以便大语言模型保持回答简短,不包括原始置信度分数。为避免每次更改时都重新实例化 InferenceClient,我将其放在不需重载的代码块中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
python复制代码if gr.NO_RELOAD:
client = InferenceClient()

system_message = {
"role": "system",
"content": """
You are a helpful assistant.
You will be given a question and a set of answers along with a confidence score between 0 and 1 for each answer.
You job is to turn this information into a short, coherent response.

For example:
Question: "Who is being invoiced?", answer: {"answer": "John Doe", "confidence": 0.98}

You should respond with something like:
With a high degree of confidence, I can say John Doe is being invoiced.

Question: "What is the invoice total?", answer: [{"answer": "154.08", "confidence": 0.75}, {"answer": "155", "confidence": 0.25}

You should respond with something like:
I believe the invoice total is $154.08 but it can also be $155.
"""}

这是我们演示的现在情况!系统消息确实帮助保持了机器人的回答简短而不包含长的小数。

应用演示带系统消息

作为最终改进,我将在页面上添加一个 Markdown 标题:

添加一个 markdown 标题

结语

在本文中,我使用 Gradio 和 Hugging Face 推理 API 开发了一个实用的 AI 应用。从开发初期,我就不确定最终产品会是什么样子,所以能够即时重新加载 UI 和服务器逻辑让我能迅速尝试各种想法。整个应用的开发过程大约只用了一个小时!

如果您想了解此演示的完整代码,请访问这个 Space 应用!

英文原文: huggingface.co/blog/gradio…

原文作者: Freddy Boulton

译者: Luke

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

1…232425…956

开发者博客

9558 日志
1953 标签
RSS
© 2025 开发者博客
本站总访问量次
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4
0%