博客

  • 解密商业文档信息提取:让电子文档处理工具为我们效力

    在现实生活中,我们常常需要将商业文档中的信息转化为结构化的格式,以便后续的系统能够解析和使用。这个过程被称为商业文档信息提取(Business Document Information Extraction,简称BDIE)。BDIE主要包括两个任务:关键信息提取(Key-Information Extraction,简称KIE)和行项目识别(Line Items Recognition,简称LIR)。本文将介绍一种全新的方法,即”检索增强结构化生成”(Retrieval Augmented Structured Generation,简称RASG),用于解决BDIE问题,并在相关基准测试中取得了最先进的成果。

    什么是商业文档信息提取?

    商业文档信息提取是将非结构化信息(如原始文本、扫描文档等)转化为结构化格式的过程,使其可以被后续的系统解析和使用。其中,关键信息提取的目标是将文档中的信息提取出来,并按照键值对的形式进行格式化。而行项目识别的目标是将信息提取为一系列行项目,其中每个行项目对应表格中的一行,并以列键值对的形式进行格式化。与表格结构识别不同的是,行项目识别不关注列的顺序,只要能够正确地将列映射到预定义的列键即可。

    检索增强结构化生成

    检索增强结构化生成(RASG)是一种由四个组件组成的方法:检索增强生成(Retrieval Augmented Generation)、监督微调(Supervised Finetuning)、结构化生成(Structured Generation)和结构化提示(Structured Prompting)。这些技术可以提高机器学习模型使用工具的能力,从而改善BDIE任务的性能。

    RASG的四个组件是相互关联的:

    1. 检索增强生成允许我们通过在上下文中进行学习,教导预训练模型使用新的工具。
    2. 监督微调提高了提取结果的正确性。
    3. 结构化生成确保模型输出的结果可以被后续的系统解析。
    4. 结构化提示将布局信息融入到提示中,使得文本提示的形式更接近原始文档。

    这四个组件在使用开源的7B大型语言模型(LLM)Hermes 2 Pro – Mistral 7B上可以取得最先进的BDIE结果。然而,在使用GPT-3.5模型时,只需要其中的一个子集即可。

    监督微调中的注意事项

    监督微调的目标是使语言模型既能输出正确的内容,又能输出正确的结构。为了确保模型输出的结果可以被后续系统解析,我们需要将无效标记的概率置零。然而,简单地将监督微调和结构化生成相结合往往会导致结果不佳。主要存在以下两个问题:

    1. 模式与模型不匹配:基于正则表达式的结构化生成算法(如Outlines’ outlines.generate.json模块)在生成过程中隐式地要求严格的键排序。例如,假设我们的模式中”amount”键在”currency”键之前。在使用Outlines时,会在生成”amount”之前屏蔽”currency”的输出。然而,如果模型被微调为在生成”amount”之前生成”currency”,预测准确性就会下降。为了解决这个问题,可以确保监督微调的数据集严格遵循指定的模式,或者使用基于上下文无关文法的结构化生成算法(例如Outlines’ outlines.generate.cfg模块),它不要求严格的键排序。
    2. 可选键带来的标记膨胀:我们经常遇到一个问题,即在预测值为空时仍然要求生成键。例如,当我们使用可选字段构建一个Pydantic对象并将其JSON模式传递给Outlines时,会生成许多不必要的标记,从而降低推理速度。另一个不好的做法是将所有键都设置为可选的。这是因为Outlines在这种情况下使用了不同的生成状态机算法。解决这个问题的方法是在模式中添加一个类型为null的必需的虚拟键,并在后处理中将其删除。

    边界框反向计算的启发式算法

    对于关键信息提取任务,我们发现一个简单的贪婪算法(算法1)就足以用于边界框的反向计算。如果要使用整个页面,可以将下边界和上边界分别设置为0和页面的高度(以像素为单位)。对于行项目识别任务,一个好的启发式算法是:(1)将页面在垂直方向上划分为多个块,每个块对应一个行项目;(2)使用上述算法1为每个行项目的分配的单词块中的单词反向计算边界框。挑战在于如何划分页面。

    算法1:边界框反向计算的启发式算法

    1. 设置下边界和上边界、预测的键值映射和OCR数据。
    2. 匹配得分、键到边界框的映射。
    3. 对于键值映射中的每对(键,值):
    • 找到边界框中的所有坐标处于下边界和上边界之间的且与值匹配的最长连续单词列表。
    • 记录匹配单词的边界框。
    • 将键到边界框的映射添加到键边界框映射中。
    1. 计算匹配分数,即所有匹配单词的相似度之和,用于评估预测结果的准确性。
    2. 返回匹配分数和键边界框映射。

    这种方法的时间复杂度为O(MN^2 * Algo1),其中M是行项目的数量,N是页面的高度。我们可以通过降低页面的规模来优化这个复杂度。在实际生产中,我们使用N=128。此外,我们利用算法1的单调性进行优化:匹配分数随着上边界的增加和下边界的减小而不增加。因此,我们可以使用分治优化来加速计算,将复杂度优化为O(MNlogN * Algo1)。最后,我们使用二分搜索来找到第一个行项目的最大下边界和最后一个行项目的最小上边界,以缩小边界范围。

    通用行项目识别度量

    行项目识别的目标是将信息提取为有序的行项目列表,其中每个行项目对应表格中的一行,并以列键值对的形式进行格式化。为了评估行项目识别的性能,我们需要一个具备以下属性的度量方法:

    1. 子任务隔离:需要分别评估子任务的性能。
    2. 单元格隔离:将一个真正的正样本对应一个预测的单元格和一个正确的真实单元格进行比较。
    3. 单元格完整性:虚构的单元格被视为假阳性,缺失的单元格被视为假阴性。
    4. 单元格相似度度量的灵活性:在同一个子任务中,度量方法应支持多种单元格相似度度量方式。
    5. 单元格行位置的不变性:对于正确预测的单元格,所给予的奖励应与其绝对行位置无关。
    6. 行顺序的保持:对于任意两个预测行,它们的相对顺序和与其匹配的真实行的相对顺序应保持一致。
    7. 列排列的不变性:度量方法应对列的重新排列具有不变性。即不考虑列的顺序。

    目前存在的行项目识别度量方法中,ANLS*和DocILE使用基于最大权重二分图匹配的算法进行行匹配,因此不满足属性#6。此外,DocILE支持单元格内容和单元格位置的识别,但无法隔离这两个方面,这使得它无法用于只进行单元格内容或单元格位置识别的任务。GriTS满足上述所有属性,但不满足属性#7。

    在接下来的部分,我们将介绍一种新的度量方法,称为通用行项目识别度量(General Line Items Recognition Metric,简称GLIRM),它满足上述所有属性。GLIRM可以看作是ANLS*和DocILE的扩展,使其满足属性#1和属性#6,同时也是GriTS的一种推广,使其满足属性#7。

    GLIRM中的相似度匹配分数

    根据属性#1和属性#4,我们将使用𝑓(𝑐ₚ, 𝑐ₜ)表示预测单元格𝑐ₚ和真实单元格𝑐ₜ之间的相似度度量。𝑓可以是适用于特定下游任务的任何相似度度量方式,如产品参考编号的精确匹配、边界框的交并比等。为了使度量方法类似于F1得分,我们需要将𝑓限制在0到1之间:0 ≤ 𝑓(𝑐ₚ, 𝑐ₜ) ≤ 1,对于所有𝑐ₚ, 𝑐ₜ。我们将使用𝑔𝑓(𝑟ₚ, 𝑟ₜ)表示预测行𝑟ₚ和真实行𝑟ₜ中对应单元格的相似度分数之和。

    行匹配

    我们将𝑅ₚ和𝑅ₜ分别表示预测的行序列和真实的行序列。我们的目标是找到等长的子序列𝑅~ₚ和𝑅~ₜ,使得对应单元格的相似度分数之和最大:
    𝑅~ₚ, 𝑅~ₜ = argmax 𝑅ₚ’ | 𝑅ₚ, 𝑅ₜ’ | 𝑅ₜ ∑ 𝑖 𝑔𝑓(𝑅~ₚ[𝑖], 𝑅~ₜ[𝑖]) (1)
    由于我们关注子序列而不是行的子集,因此更适合使用类似Levenshtein距离的算法来找到𝑅~ₚ和𝑅~ₜ,而不是像ANLS*和DocILE那样使用基于最大权重二分图匹配的算法。这样可以惩罚在预测中交换或重新排列的行。

    GLIRM的准确率(GLIRM-Prec)和召回率(GLIRM-Rec)可以定义如下:
    GLIRM-Prec(𝑅ₚ, 𝑅ₜ) = (1/|𝑅ₜ|) ∑ 𝑖 𝑔𝑓(𝑅~ₚ[𝑖], 𝑅~ₜ[𝑖]) (2)
    GLIRM-Rec(𝑅ₚ, 𝑅ₜ) = (1/|𝑅ₚ|) ∑ 𝑖 𝑔𝑓(𝑅~ₚ[𝑖], 𝑅~ₜ[𝑖]) (3)
    GLIRM-F1(𝑅ₚ, 𝑅ₜ)可以定义为:
    GLIRM-F1(𝑅ₚ, 𝑅ₜ) = (1+𝛽²) ∑ 𝑖 𝑔𝑓(𝑅~ₚ[𝑖], 𝑅~ₜ[𝑖]) / (𝛽²|𝑅ₚ| + |𝑅ₜ|) (4)
    在实际应用中,或者当人工审核系统的输出时,召回率通常比准确率更重要。这是因为查找并确定缺失单元格比验证提取单元格的正确性需要更多时间。因此,我们可以定义带有𝛽参数的GLIRM-F1指标:
    GLIRM-F1𝛽(𝑅ₚ, 𝑅ₜ) = (1+𝛽²) ∑ 𝑖 𝑔𝑓(𝑅~ₚ[𝑖], 𝑅~ₜ[𝑖]) / (𝛽²|𝑅ₚ| + |𝑅ₜ|) (5)
    其中𝛽是一个控制召回率重要性的超参数。当𝛽=1时,该指标与GLIRM-F1相同。

    实验结果

    我们使用DocILE数据集进行了实验。表格I比较了LLMs与RASG在KIE和LIR任务上的性能与强大的多模态基线(如LayoutLMv3和Roberta + DETR)。表格II显示了RASG各组件在不同基线模型上的贡献。

    在KIE任务上,只需要GPT-3.5 + 1-Shot Retrieval或Hermes 2 Pro + RASG即可超越基线。对于LIR任务,GPT-3.5 + 1-Shot Retrieval + Structured Prompting就足以击败基线模型。

    此外,我们还测量了边界框反向计算启发式算法的中位数表格级信息覆盖得分(Information Coverage Score,简称ICS)。最佳基线模型Roberta + finetuned DETR在ICS上达到92.93%,而GPT-3.5 + RASG和Hermes 2 Pro + RASG分别达到87.79%和85.02%。

    讨论与结论

    我们的模型性能和消融实验结果表明了几个结论。首先,在KIE任务中,与其进行提示工程相比,使用检索机制和/或在目标数据集上进行微调的效果更好。对于LIR任务,首先进行结构化提示,然后再进行微调是一个更好的策略。有趣的是,经过适当调整和增强的LLMs可以击败经过微调的多模态模型,如LayoutLMv3和Roberta + DETR。最后,我们提出的边界框反向计算启发式算法在表格检测任务上的性能仅略逊于最佳基线模型。

    对于在商业文档信息提取领域工作的团队,我们建议首先使用支持结构化生成的现成LLMs模型,然后实现检索机制。如果性能仍然不理想,可以考虑进行监督微调。对于LIR任务,我们建议先从结构化提示开始,然后再进行微调。

    综上所述,本文介绍了使用RASG框架解决BDIE问题的全面方法,并提供了关于LLMs在这一领域中性能和优化策略的见解。

    参考文献:

    • Franz Louis Cesista, Rui Aguiar, Jason Kim, Paolo Acilo. Retrieval Augmented Structured Generation: Business Document Information Extraction As Tool Use.
    • Skalický, Jakub, et al. “Business document information extraction.” arXiv preprint arXiv:2202.06070 (2022).
    • Smock, Matthew, et al. “GriTS: A Generalized Table Structure Recognition Metric.” arXiv preprint arXiv:2304.01428 (2023).
    • Willard, Willard. “Outlines: A toolkit for building structured generation models.” arXiv preprint arXiv:2303.01632 (2023).
    • Xiao, Tong, et al. “Information Coverage Score: Measuring Table Structure Extraction Quality.” arXiv preprint arXiv:2311.00007 (2023).
    • Simsa, Jiří, et al. “DocILE: A Large-scale Research Benchmark for Document Key Information Extraction and Line Item Recognition.” arXiv preprint arXiv:2312.00212 (2023).
    • Huang, Xingyi, et al. “LayoutLMv3: Multi-modal Pre-training for Visually Rich Document Understanding.” arXiv preprint arXiv:2203.06470 (2022).
    • Liu, Yinhan, et al. “Roberta: A robustly optimized BERT pretraining approach.” arXiv preprint arXiv:1907.11692 (2019).
    • Carion, Nicolas, et al. “End-to-end object detection with transformers.” arXiv preprint arXiv:2005.12872 (2020).
  • 新的位置编码CoPE

    新的位置编码方法 CoPE(Contextual Position Encoding)确实在提升大模型性能方面展示了显著的潜力。传统的 Transformer 模型使用绝对或相对位置编码,通常基于 token 的位置来进行编码,这在处理更高层次的抽象任务(例如计算第 i 个句子或特定单词)时存在局限性。而 CoPE 通过允许模型根据上下文来选择性地编码位置,解决了这一问题。

    CoPE 的优点

    1. 上下文依赖的位置编码:CoPE 通过计算每个 query-key 对的门控值(gate value)来决定哪些 token 应该被计入位置测量。这使得位置测量不再是简单的 token 计数,而是根据内容和上下文动态调整。
    2. 多层次位置抽象:CoPE 能够同时表示从 token 位置到句子位置等不同层次的抽象位置。这样,模型不仅能关注到前几个 token,还能关注到前几个句子,从而更好地理解当前句子的含义。
    3. 跨任务的优越性能:文章通过多个实验展示了 CoPE 在处理选择性复制、计数任务以及语言和编码任务中的优越性,特别是在处理分布外数据和需要高泛化能力的任务上表现出更强的性能。

    实验结果

    实验结果表明,CoPE 在以下几个方面优于传统的位置编码方法:

    • 选择性复制和计数任务:CoPE 能够解决标准位置编码方法无法解决的选择性复制和计数任务。
    • 语言建模和编码任务:在这些实际应用中,CoPE 降低了困惑度(perplexity),提高了模型性能。
    • 分布外数据的泛化能力:CoPE 在处理分布外数据时表现出更强的泛化能力,这是传统位置编码方法难以实现的。

    结论

    总的来说,CoPE 提供了一种更灵活、更强大的位置编码方法,适用于需要对输入数据结构和语义内容进行精细理解的任务。通过上下文依赖的位置编码,CoPE 能够显著提升大模型在多种任务上的性能,特别是在需要高泛化能力的场景中。

    论文链接:Encoding: Learning to Count What’s Important

  • 美国软件股大崩盘的启示:至少在现阶段,AI对软件是替代、而非增益!


    AI投资狂潮主要催生了芯片制造和云计算需求,而软件企业距离从中获利仍有一段距离。在人工智能热潮的强劲推动下,科技行业当前正上演着前所未有的剧烈洗牌。本周软件和企业科技公司的财报就暴露出这一转折期的阵痛——业绩普遍疲软,前景飘忽不定。

    软件公司距离从AI热潮获利仍有一段距离

    分析人士指出,目前AI投资狂潮主要催生了芯片制造和云计算需求,而软件企业距离从中获利仍有一段距离。

    彭博智库高级分析师 Anurag Rana 表示,除微软外,目前很少软件公司的收入有所提振,资金主要流向了英伟达等芯片巨头以及云计算平台。

    大多数公司都没有专门的AI预算,所以他们只能从非AI预算中挪用资金。他们仍在购买英伟达芯片和戴尔服务器,但不会签订大额软件合同。软件行业最终将从AI中获益,但要建立起来可能需要数年时间,今年下半年的业绩改善已经无望实现。

    曾经作为行业明星的 Salesforce 本周四绩后股价大跌近20%,创2004年上市以来最大单日跌幅。业绩不佳固然是导火索,但公司高管的表态更彰显出软件企业面临的窘境。

    Salesforce CEO 贝尼奥夫直言,过往疫情催生的“虚假繁荣”正在消退。当年为适应远程办公需求而大量采购的软硬件,如今亟需进行整合和理顺。

    他认为:

    每家企业软件公司都在疫后进行了调整,最近发布财报公司基本上都在以不同方式重复同样的话。

    除了 Salesforce,Okta、MongoDB、UiPath 等公司也在最新财报中下调了全年收入预期。Okta 直指宏观经济环境成为拖累,影响了新客户的获取及现有客户的购买扩展。

    而在 Veeva 的财报电话会议上,CEO 甚至将通用 AI 列为客户”优先权重新分配”的一大原因。类似的景象几乎笼罩了整个软件和企业科技行业。

    宏观环境低迷 企业主要资金流向硬件升级

    另一个潜在阻力则是宏观经济的持续低迷。在本周公布的最新 PCE 物价指数数据显示,通胀水平微高于预期,美联储也维持利率在23年高位不变。在这种环境下,企业对于签订长期软件订单的热情自然会大打折扣。

    UiPath 创始人 Daniel Dines 指出,UiPath 在3月下旬和4月份遭遇了严重业务放缓,部分原因就是当前经济状况乏力,客户对包年合同需求大幅降温,转而青睐短期订单。

    戴尔财报也显示,由于更多低利润的 AI 服务器订单涌入,全年毛利率料将下滑 150 个基点。这一点也从侧面说明了软件需求疲软、企业预算多转向硬件的局面。

    在 AI 火热的发展背后,科技行业正加速分化重组。芯片、云计算等直接相关领域获利最大,而软件企业则承受了较大冲击,不得不通过收缩支出、放缓扩张甚至裁员来应对。

    例如 SentinelOne CEO 就直言,企业的采购习惯和软件评估标准都在发生变化。这种动能切换对于整个软件行业来说都是个重大考验。一旦脱离 AI 趋势而错失良机,后果可能是被行业洗牌甩在后面。

    不过,也有分析人士认为,目前软件股的大幅回调恰恰为投资者提供了良机。伯恩斯坦分析师认为,像 ServiceNow 这样获利确定性较高的头部公司在估值修复后反而更具投资价值。

  • 文章标题:谁在写评论,是人还是AI?

    人工智能(AI)的广泛应用在自然语言处理领域引发了一个问题:如何准确区分AI生成的文本和人类编写的文本?一篇最新的研究提出了一种方法来解决这个问题,它通过使用迁移学习技术,让模型能够在不同主题下识别生成文本,同时提高对写作风格和词汇变化的检测能力。

    研究人员使用了一个包含真实书评和AI生成书评的数据集,通过开源的Vicuna语言模型生成了AI评论。经过实验验证,这种方法能够准确地区分AI生成的文本和人类编写的文本,实现了96.86%的准确率。这项研究的目标是探索大型语言模型在文本识别方面的能力和局限性,并为未来有效地识别和管理AI生成的内容提供有价值的经验。

    解决问题的方法:迁移学习和数据集准备

    为了解决区分AI生成文本和人类编写文本的问题,研究人员采用了以下方法:

    迁移学习

    迁移学习是一种将在一个任务上训练得到的模型应用于另一个相关任务的技术。在这项研究中,研究人员利用之前在科学摘要分类任务中训练得到的模型权重,通过迁移学习技术对模型进行微调,以适应书籍评论领域的文本分类任务。这种方法可以提高模型在不同主题下识别生成文本的能力。

    数据集准备

    研究人员使用了一个包含真实书评和AI生成书评的数据集。具体来说,他们从Kaggle上获取了一个公开的书籍评论数据集,并使用开源的Vicuna模型生成了对应的AI书籍评论。这个数据集包含了10,000条人类评论和10,000条AI生成评论,用于训练和评估模型。

    实验和结果分析

    在实验过程中,研究人员对模型进行了训练和评估,并分析了实验结果。

    数据预处理和文本表示

    在训练模型之前,研究人员对收集到的书籍评论进行了清洗和预处理。他们去除了特殊字符、空白、停用词,并将文本转换为小写格式,以提高数据质量。然后,他们使用Word2Vec技术中的”google-news-300″预训练模型将文本转换为300维的向量表示,以捕捉词义和上下文关系。

    模型架构和训练

    研究人员采用了长短期记忆网络(LSTM)来处理序列数据,并在LSTM后加入dropout层以减少过拟合。为了适应书籍评论领域的文本分类任务,他们使用迁移学习技术对模型进行微调。

    性能评估和结果分析

    通过使用准确率、精确率、召回率、F1分数和AUC等指标,研究人员评估了模型的性能。实验结果显示,使用迁移学习后,模型的平均准确率提高到了96.86%。

    此外,研究人员还对模型的分类结果进行了分析。他们可视化了模型正确分类和错误分类的文本,并对错误分类的文本进行进一步的分析。他们通过词云图展示了这些文本中的词汇使用情况,并使用t-SNE方法将模型隐藏状态的高维表示降维到2D空间,以可视化人类编写和AI生成文本的分离情况。

    进一步的研究方向

    尽管这项研究取得了显著的成果,但还有一些进一步的研究方向值得探索:

    • 跨领域应用:将所提出的方法应用于其他文本领域和类型,如推文(tweets),以测试模型在没有进一步训练的情况下是否能够检测AI生成的文本。
    • 使用更先进的语言模型:尝试使用更新的、更先进的开源语言模型来生成更大的数据集,这将有助于改进文本生成方法,并在不同领域、语言和文本类型中测试其有效性。
    • 深入理解AI内容的潜力和局限性:通过研究生成的文本,进一步了解AI产生内容的潜力和局限性。
    • 改进模型架构和文本表示方法:探索其他类型的循环神经网络(RNN)或变换器模型(如Transformer或BERT),以及其他文本表示技术,如BERT或ELMo,以进一步提高模型的性能。
    • 多模态数据集:考虑将文本数据与其他类型的数据(如图像或声音)结合起来,以研究AI在生成多模态内容方面的能力。
    • 伦理和社会影响:研究AI生成文本的伦理和社会影响,包括对隐私、版权和信息真实性的影响。
    • 对抗性训练:使用对抗性训练技术来提高模型对AI生成文本的鲁棒性,特别是在面对越来越复杂的文本生成策略时。
    • 实时检测系统:开发实时检测系统,以便在文本生成后立即识别AI生成的文本。
    • 用户研究:进行用户研究,了解人们如何感知AI生成的文本,并探索如何提高人类对AI文本的识别能力。

    结论

    这项研究提出了一种有效的方法来区分AI生成的文本和人类编写的文本。通过迁移学习和适当的文本表示技术,可以准确识别AI生成的文本,并在实验中实现了96.86%的准确率。然而,需要进一步的研究来探索AI在文本生成方面的潜力和局限性,并开发出更有效的工具来检测和管理AI生成的内容。

    参考文献:

  • 为什么大型语言模型需要适应不同用户群体的偏好?

    大型语言模型(LLMs)是一类强大的人工智能模型,可以处理和生成自然语言文本,如文章、对话和翻译。这些模型在许多任务上表现出色,但它们通常需要经过微调来适应特定的任务或用户需求。

    微调LLMs的常用方法是通过强化学习与人类反馈(RLHF)来调整模型的偏好。这意味着让人类标注者提供关于不同文本选项的偏好,然后通过优化模型的策略来使其更符合这些偏好。然而,这些偏好数据通常来自不同的标注者群体,他们可能具有不同的文化背景、语言特点、年龄、性别等特征。

    传统的RLHF方法存在一个问题,它们采用了所谓的“一刀切”策略,即假设所有群体的偏好是一致的,并且只优化一个单一的偏好模型。然而,不同群体的偏好可能存在差异,这可能导致模型在特定群体中的性能不佳。例如,一个模型在年轻人中可能表现出色,但在年长的用户中则可能表现不佳。

    为了解决这个问题,研究人员提出了一种名为Group Robust Preference Optimization(GRPO)的方法,旨在使LLMs能够更好地适应不同用户群体的偏好。GRPO方法考虑了不同群体的独特特征和需求,并通过优化策略以最大化最差情况下的群体性能来提高模型的鲁棒性。

    GRPO方法是如何工作的?

    GRPO方法通过以下关键步骤来优化LLMs以适应不同用户群体的偏好:

    1. 群体信息整合

    与传统方法不同,GRPO方法将来自不同群体的偏好数据整合到模型训练中。这意味着模型会考虑多个偏好分布,而不是仅仅假设一个单一的分布。

    2. 最坏情况性能优化

    GRPO方法的目标是优化策略,使得模型在最坏情况下的群体性能也能得到最大化。具体而言,它通过最大化不同群体损失的最小值来实现。这意味着模型将努力在最差表现的群体中保持较好的性能。

    3. 自适应权重调整

    GRPO方法根据不同群体的累积损失动态调整权重,以优先考虑那些累积损失较大的群体。这样做可以确保模型更关注性能较差的群体,并在后续的训练中给予它们更多的重视。

    4. 理论分析与算法设计

    为了保证GRPO方法的可行性,研究人员进行了理论分析,并设计了相应的算法来解决群体鲁棒偏好优化问题。他们提供了一些收敛性保证,以确保算法能有效地优化模型策略。

    5. 实验验证

    研究人员在合成数据集和真实世界数据上进行了实验验证GRPO方法的有效性。他们发现,通过使用GRPO方法微调LLMs,可以显著提高最差表现群体的性能,并减少不同群体之间的性能差距。实验结果显示,GRPO方法相比非鲁棒基线在损失和准确性方面取得了显著的改进。

    GRPO方法的应用前景和未来工作

    GRPO方法的提出为解决LLMs在不同用户群体间偏好对齐的问题提供了一种新的解决方案。通过考虑不同群体的特征和需求,GRPO方法能够使模型更加鲁棒和公平,提高用户体验。

    未来的研究可以进一步探索以下方向:

    • 提高算法效率,尤其是在处理大规模数据集和复杂模型时。
    • 更精细的超参数调整策略,以适应不同的应用场景和数据分布。
    • 探索其他类型的损失函数,以进一步提高模型的鲁棒性和性能。
    • 考虑更广泛的群体特征,如文化、语言和社会经济背景,以实现更全面的群体鲁棒性。
    • 在更广泛的实际应用中测试GRPO方法,如医疗、教育和商业领域,以验证其在现实世界中的有效性。
    • 进一步研究群体间和群体内的差异,以及如何平衡这些差异以实现最佳的模型性能。
    • 提高模型的解释性,以更好地理解不同群体偏好如何影响模型的决策。

    通过在这些方向上进行进一步的研究,可以提高GRPO方法的实用性、有效性和泛化能力,从而更好地服务于多样化的用户群体。

    参考文献:

    • Shyam Sundhar Ramesh, Yifan Hu, Iason Chaimalas, Viraj Mehta, Pier Giuseppe Sessa, Haitham Bou Ammar, Ilija Bogunovic. (2024). Group Robust Preference Optimization in Reward-free RLHF. [PDF13] [Copy] [Kimi33]
  • S3D:低内存GPU上的自推测解码方案

    引言

    大型语言模型(Large Language Models,LLMs)在自然语言处理领域起着重要作用,能够生成人类语言的连续文本,为我们提供强大的语言处理能力。然而,LLMs在推理过程中面临一个重要问题,即幻觉(Hallucination)问题。幻觉指的是模型生成看似合理但实际上不准确的信息,这可能导致误导性的结果和信息的传播。

    为了更好地理解和解决LLMs中的幻觉问题,研究者们进行了大量的研究工作。其中一篇关于幻觉问题的研究论文是《S3D: A Simple and Cost-Effective Self-Speculative Decoding Scheme for Low-Memory GPUs》。这篇论文提出了一种名为Skippy Simultaneous Speculative Decoding(简称S3D)的自推测解码方案,旨在解决在低内存GPU上进行LLM推理时的性能和内存限制问题。

    S3D方案解决的问题

    S3D方案的目标是解决在低内存GPU上进行LLM推理时的性能和内存限制问题。传统的推测解码方法在高端设备上实现了显著的加速,但在低内存设备上却存在性能下降的问题。此外,量化带来的内存开销也限制了LLMs在低内存GPU上的应用。因此,S3D方案旨在提供一种成本效益高、适用于低内存GPU的自推测解码方法。

    相关研究

    在幻觉问题的研究领域,已经有许多相关研究取得了重要进展。其中,早期的推测解码方法、多标记预测、雅可比迭代方法、层跳过技术以及其他SD系统等都与S3D方案有一定的关联。

    S3D方案的关键内容

    S3D方案提出了Skippy Simultaneous Speculative Decoding(S3D)方法,通过同时多标记预测和中层跳过的方式实现自推测解码。S3D方法不需要额外的显存成本,同时具备高训练效率。与其他SD系统相比,S3D方法在性能-内存比率方面表现出色,且无需进行大规模的架构调整和训练数据的修改。

    实验验证

    论文中进行了一系列实验来验证S3D方案的性能。实验结果表明,S3D在性能-内存比率方面表现出色,相较于其他开源SD系统,具有更好的性能。此外,论文还进行了成本效益和速度的比较实验,验证了S3D方案的有效性和实用性。

    进一步的研究方向

    尽管S3D方案已经取得了一定的研究成果,但仍有一些潜在的研究方向值得进一步探索。这些方向包括适配器技术、更广泛的硬件评估、更深入的超参数优化、模型泛化能力、量化和稀疏性、并行化和分布式训练、实时应用、鲁棒性和错误分析、与其他优化技术的集成、用户研究和应用案例等。

    通过进一步的研究探索,可以更好地理解S3D方案的潜绪和局限性,并推动其在更广泛的领域中的应用。

    结论

    《S3D: A Simple and Cost-Effective Self-Speculative Decoding Scheme for Low-Memory GPUs》论文提出了一种名为S3D的自推测解码方案,旨在解决低内存GPU上进行LLM推理时的性能和内存限制问题。S3D方案通过同时多标记预测和中层跳过的方式实现自推测解码,具备成本效益高、训练效率高的优点。实验结果表明S3D在性能和内存比率方面表现出色,并具有实际应用的潜力。进一步的研究可以在适配器技术、更广泛的硬件评估、模型泛化能力等方面开展,以推动S3D方案的发展和应用。

    参考文献:

    • Wei Zhong, Manasa Bharadwaj. “S3D: A Simple and Cost-Effective Self-Speculative Decoding Scheme for Low-Memory GPUs.” 2024.

    S3D (Skippy Simultaneous Speculative Decoding) is a simple and cost-effective self-speculative decoding scheme designed for low-memory GPUs. It aims to achieve fast inference, low VRAM costs, and high training efficiency [1].

    Speculative decoding (SD) is a technique that accelerates low-latency model (LLM) inference without sacrificing quality. It works by drafting tokens at a faster speed and then verifying the guessed tokens at the end of an iteration using a full forward pass. However, existing SD methods often achieve optimal performance on high-end devices or with a substantial GPU memory overhead. When applied to smaller models or low-memory devices where quantization is necessary, these methods can experience significant slowdowns [1].

    To address these challenges, S3D introduces mid-layer skipping and simultaneous multi-token predictions. It offers no added VRAM costs and high training efficiency. By leveraging memory efficiency, S3D demonstrates optimal performance-memory ratios among recent open-source SD models. It can avoid significant quantization overheads under certain VRAM constraints and outperform previous SD methods under 8-bit quantization by up to 3.9x in speedups on A10G GPU [1].

    S3D also provides optimal hyper-parameters by formalizing the relationship between the number of skipped layers and speedup in self-speculative decoding. It can verify the optimal number of token predictors, leading to improved performance [1].

    In summary, S3D is a cost-effective self-speculative decoding scheme that achieves fast inference, low VRAM costs, and high training efficiency for low-memory GPUs. It overcomes the limitations of existing SD methods and demonstrates optimal performance-memory ratios [1].


    Learn more:

    1. S3D: A Simple and Cost-Effective Self-Speculative Decoding Scheme for Low-Memory GPUs
    2. GitHub – hemingkx/SpeculativeDecodingPapers: 📰 Must-read papers and blogs on Speculative Decoding ⚡️
    3. [2309.08168] Draft & Verify: Lossless Large Language Model Acceleration via Self-Speculative Decoding

    S3D是一种简单且经济高效的自我推测解码方案,专为低内存GPU设计。该方法通过同时进行多令牌解码和中间层跳过来实现推测解码,既不增加显存开销,又具有高训练效率[1]

    S3D的主要特点和贡献包括:

    1. 有效的自我推测解码:S3D采用了中间层跳过和同时进行多令牌预测的简单且节省内存的自我推测解码方案。相比之前的方法,S3D在较小的模型上克服了速度上的限制[1]
    2. 最优超参数:S3D通过对自我推测解码中跳过层数和速度提升之间关系的形式化研究,确定了最优的令牌预测器数量[1]
    3. 最优速度-内存比:S3D在最近的开源自我推测解码模型中展现出最优的性能-内存比。通过利用内存效率,S3D可以避免在特定显存限制下进行量化时产生的显著开销,并在A10G GPU上在8位量化下比之前最快的SD方法(EAGLE)提升了3.9倍的速度[1]

    相关工作方面,早期的自我推测解码方法主要集中在特定领域任务上,如翻译和语法错误修正,这些任务很容易实现显著的加速。而S3D则针对通用领域任务,通过同时预测多个令牌和非批处理解码来节省内存并提高训练效率[2]


    Learn more:

    1. S3D: A Simple and Cost-Effective Self-Speculative Decoding Scheme for Low-Memory GPUs
    2. [2405.20314] S3D: A Simple and Cost-Effective Self-Speculative Decoding Scheme for Low-Memory GPUs
    3. GitHub – hemingkx/SpeculativeDecodingPapers: 📰 Must-read papers and blogs on Speculative Decoding ⚡️
  • 分析大型语言模型中的幻觉问题

    引言

    大型语言模型(Large Language Models,LLMs)在自然语言处理领域扮演着重要的角色,它们可以生成人类语言的连续文本,为我们提供了强大的语言处理能力。然而,随着模型规模的增大和训练数据的增加,LLMs也面临着一个严重的问题,即幻觉(Hallucination)问题。幻觉指的是模型生成看似合理但实际上不准确的信息,这可能导致误导性的结果和信息的传播。

    为了更好地理解和解决LLMs中的幻觉问题,研究者们进行了大量的研究工作。其中一篇关于幻觉问题的研究论文是《Analytical Annotation of Hallucinations in Large Language Models (ANAH)》。这篇论文提出了一种分析性注释的方法,以便更详细地研究和量化LLMs中的幻觉问题。

    ANAH数据集:详细注释LLMs中的幻觉

    为了深入研究LLMs中的幻觉问题,研究者们创建了一个名为ANAH的双语数据集。ANAH数据集提供了对LLMs在生成式问答(Generative Question Answering)任务中幻觉问题的分析性注释。数据集中的每个答案句子都经过了严格的注释,包括参考片段的检索、幻觉类型的判断以及对幻觉内容的更正。

    ANAH数据集由人工和自动化注释流程构建而成。通过这个数据集,研究者们能够量化和分析LLMs中幻觉的累积效应,并训练和评估幻觉注释器的性能。实验结果表明,经过训练的生成性幻觉注释器在性能上能够与最先进的模型相媲美,并展现出更好的泛化能力。

    幻觉问题的研究进展

    幻觉问题在自然语言处理领域一直备受关注。研究者们提出了多种方法来解决幻觉问题,包括幻觉检测和评估、幻觉缓解、基准测试、知识增强等。这些方法的目标都是提高模型的可靠性和准确性,减少幻觉的产生。

    例如,为了评估幻觉问题,研究者们构建了各种基准测试集,设计了挑战性的问题,并通过评估答案中幻觉的水平来衡量模型的性能。此外,还有一些研究探索了如何在模型的训练和推理阶段减轻幻觉问题,例如通过多任务学习、模型编辑和强化学习等方法。

    未来的研究方向

    尽管已经取得了一些进展,但解决LLMs中的幻觉问题仍然是一个具有挑战性的任务。未来的研究可以在以下几个方向上进行探索:

    1. 数据集扩展:将ANAH数据集的规模扩大,覆盖更广泛的主题和任务,以更全面地理解和解决幻觉问题。
    2. 模型泛化能力:研究如何提高模型在未见主题和未见问题上的泛化能力,使其能够更好地应对各种情况。
    3. 训练策略优化:探索不同的训练策略,如半监督学习、元学习等,以提高模型在有限数据上的性能和泛化能力。
    4. 提高模型解释性:研究如何提高幻觉注释器的解释性,使其能够提供更详细的解释和证据,以支持其注释和纠正决策。
    5. 多模态和跨语言能力:考虑多模态数据(如图像、视频)和跨语言能力,以提高模型对不同类型输入的理解和生成能力。
    6. 模型鲁棒性:进一步提高模型对对抗性攻击和输入扰动的鲁棒性。
    7. 长期影响评估:评估幻觉注释器在长期应用中的效果,包括用户对模型输出的信任度和依赖性的变化。
    8. 知识更新和维护:研究如何定期更新和维护模型的知识库,以确保其提供的信息是最新和准确的。
    9. 用户定制化和个性化:探索如何根据用户的特定需求和偏好定制化和个性化模型的输出。

    这些研究方向将有助于进一步提高LLMs的可靠性、准确性和用户满意度。

    结论

    本文总结了《Analytical Annotation of Hallucinations in Large Language Models (ANAH)》论文的主要内容。该论文通过创建详细的注释数据集和训练幻觉注释器,提供了一种系统的框架来研究和解决LLMs中的幻觉问题。幻觉注释器能够提高模型的可靠性并减少幻觉的产生。然而,幻觉问题仍然具有挑战性,需要进一步的研究来改进模型的性能和泛化能力。

    参考文献:

    • Ziwei Ji, Yuzhe Gu, Wenwei Zhang, Chengqi Lyu, Dahua Lin, Kai Chen. “Analytical Annotation of Hallucinations in Large Language Models (ANAH).” 2024.
  • 通俗易懂:理解ICE协议及其Java实现ice4j

    引言

    在网络通信中,当涉及到穿越网络地址转换(NAT)设备时,传统的通信协议可能会面临一些挑战。为了解决这个问题,我们需要使用一种特殊的协议来实现穿越NAT设备的功能。其中一种常用的协议是ICE(Interactive Connectivity Establishment)协议,它将STUN(Simple Traversal of UDP through NAT)和TURN(Traversal Using Relays around NAT)等工具结合起来,为基于Offer/Answer的协议(如SIP和XMPP)提供了一种强大的穿越NAT的机制。

    在本文中,我们将介绍ICE协议及其在Java中的实现ice4j。我们将详细讨论ICE协议的原理、作用,以及ice4j项目的特点和用途。让我们一步步深入了解ICE协议及其Java实现ice4j吧!

    ICE协议的原理和作用

    ICE协议是一种用于解决NAT穿越问题的协议。它通过结合STUN和TURN等工具,提供了一种机制来使基于Offer/Answer的协议能够穿越NAT设备。

    ICE协议的核心思想是在通信的两端(称为对等体)之间建立一个可靠的连接。ICE协议通过以下步骤实现穿越NAT的功能:

    1. 收集候选地址:对等体收集自己的IP地址和端口号,并将其作为候选地址。这些候选地址可以是本地的IP地址,也可以是通过STUN服务器获取的公网地址。
    2. 建立连接:对等体之间交换候选地址,然后根据一系列规则和优先级选择最佳的候选地址来建立连接。
    3. NAT穿越:如果对等体之间的直接连接无法建立,ICE协议将尝试使用TURN服务器作为中继来实现穿越NAT。

    通过以上步骤,ICE协议能够有效地解决NAT穿越的问题,确保通信双方能够建立可靠的连接。

    ice4j项目的特点和用途

    ice4j是一个用Java实现的ICE协议库,它提供了一些特色功能和用途,使其成为开发者们首选的ICE协议实现之一。

    1. 简化开发:ice4j提供了一套简单易用的API,使开发者能够快速、方便地集成ICE协议功能到他们的应用程序中。
    2. 支持Pseudo TCP:除了基本的ICE功能,ice4j还支持Pseudo TCP协议,这是一种通过UDP模拟TCP连接的技术。它提供了可靠的数据传输,并通过模拟TCP的流量控制和拥塞控制来优化传输性能。
    3. Socket共享:ice4j支持在多个应用程序之间共享同一个UDP套接字,这样可以有效地减少网络资源的占用。

    通过使用ice4j,开发者们可以轻松地实现ICE协议的功能,从而使他们的应用程序能够在复杂的网络环境中实现可靠的通信。

    ice4j的应用举例

    以下是一些使用ice4j的典型应用场景:

    1. 即时通信应用:ice4j可以用于构建支持实时音视频通信的应用程序,如视频会议、在线聊天等。它能够帮助应用程序穿越NAT设备,实现可靠的点对点通信。
    2. WebRTC应用:WebRTC是一种用于在Web浏览器中实现实时通信的技术,而ICE协议是WebRTC的核心组成部分之一。通过使用ice4j,开发者可以轻松地在WebRTC应用中实现NAT穿越和建立可靠的连接。
    3. 网络游戏:在网络游戏中,玩家之间需要建立可靠的连接以进行实时游戏交互。通过使用ice4j,开发者可以实现游戏服务器和客户端之间的可靠通信,提供流畅的游戏体验。

    总结

    ICE协议及其Java实现ice4j为解决NAT穿越问题提供了一种强大的机制。通过收集候选地址、建立连接和使用中继服务器,ICE协议能够实现可靠的点对点通信。ice4j作为ICE协议的Java实现,提供了简化开发、支持Pseudo TCP和Socket共享等特色功能,使开发者能够轻松地集成ICE协议功能到他们的应用程序中。

    参考文献:

  • ActivityPub:去中心化社交网络协议

    ActivityPub 是一个去中心化的社交网络协议,基于 ActivityStreams 2.0 数据格式。它提供了从客户端到服务器的 API,用于创建、更新和删除内容,以及一个从服务器到服务器的 API,用于传递通知和内容。本文将深入探讨 ActivityPub 的核心概念和实现方式。

    什么是 ActivityPub?

    ActivityPub 是一种标准化的协议,旨在实现去中心化的社交网络。它包括两个主要部分:

    1. 客户端到服务器的协议:允许用户(包括真实用户、机器人和其他自动化进程)通过他们在服务器上的账户与 ActivityPub 通信。这可以通过手机、桌面应用或网页应用实现。
    2. 服务器到服务器的协议:使去中心化网站能够共享信息和内容。

    基本概念

    在 ActivityPub 中,用户通过其在服务器上的账户表示为“actors”。每个 actor 都有一个收件箱(inbox)和发件箱(outbox),用于接收和发送消息。

    {
      "@context": "https://www.w3.org/ns/activitystreams",
      "type": "Person",
      "id": "https://social.example/alyssa/",
      "name": "Alyssa P. Hacker",
      "preferredUsername": "alyssa",
      "summary": "Lisp enthusiast hailing from MIT",
      "inbox": "https://social.example/alyssa/inbox/",
      "outbox": "https://social.example/alyssa/outbox/",
      "followers": "https://social.example/alyssa/followers/",
      "following": "https://social.example/alyssa/following/",
      "liked": "https://social.example/alyssa/liked/"
    }

    客户端到服务器的交互

    客户端通过向 actor 的发件箱(outbox)发送 POST 请求来发布活动。请求必须包含一个 Activity 对象,服务器随后会将其处理并传递到目标收件箱。

    发布活动示例

    假设 Alyssa 想给她的朋友 Ben 发送一条消息,询问他是否还书。她的消息可以表示为一个 ActivityStreams 对象,并通过 POST 请求发送到她的 outbox。

    {
      "@context": "https://www.w3.org/ns/activitystreams",
      "type": "Note",
      "to": ["https://chatty.example/ben/"],
      "attributedTo": "https://social.example/alyssa/",
      "content": "Say, did you finish reading that book I lent you?"
    }

    服务器会将此消息包装在一个 Create 活动中,并将其 POST 到 Ben 的收件箱。

    接收消息

    Alyssa 的手机会通过 GET 请求轮询她的收件箱,以获取新消息。当 Ben 回复了她的消息,她会看到如下内容:

    {
      "@context": "https://www.w3.org/ns/activitystreams",
      "type": "Create",
      "id": "https://chatty.example/ben/p/51086",
      "to": ["https://social.example/alyssa/"],
      "actor": "https://chatty.example/ben/",
      "object": {
        "type": "Note",
        "id": "https://chatty.example/ben/p/51085",
        "attributedTo": "https://chatty.example/ben/",
        "to": ["https://social.example/alyssa/"],
        "inReplyTo": "https://social.example/alyssa/posts/49e2d03d-b53a-4c4c-a95c-94a6abf45a19",
        "content": "<p>Argh, yeah, sorry, I'll get it back to you tomorrow.</p><p>I was reviewing the section on register machines, since it's been a while since I wrote one.</p>"
      }
    }

    服务器到服务器的交互

    服务器之间通过向 actor 的收件箱发送 POST 请求来传递消息。这种交互方式允许去中心化的社交网络跨不同服务器传递信息。

    示例:服务器间的消息传递

    当 Alyssa 发布一条消息到她的 outbox,服务器会查找消息的目标收件箱,并将消息 POST 到这些收件箱。这样,Ben 的服务器就能接收到 Alyssa 的消息,并将其存储在 Ben 的收件箱中。

    安全性与认证

    ActivityPub 使用认证机制来验证客户端与服务器之间、以及服务器与服务器之间的互动。为了确保内容的真实性,服务器应验证接收到的内容,确保其来自声称的 actor,并且该 actor 有权限更新资源。

    验证示例

    服务器在接收到一个活动后,应验证该活动的 idactor 属性,确保其真实性。例如:

    {
      "@context": "https://www.w3.org/ns/activitystreams",
      "type": "Like",
      "actor": "https://example.net/~mallory",
      "to": ["https://hatchat.example/sarah/", "https://example.com/peeps/john/"],
      "object": {
        "@context": {"@language": "en"},
        "id": "https://example.org/~alice/note/23",
        "type": "Note",
        "attributedTo": "https://example.org/~alice",
        "content": "I'm a goat"
      }
    }

    服务器应确保 idactor 属性合法,并查验对象是否由 actor 创建。

    结论

    ActivityPub 通过提供去中心化的社交网络协议,实现了更高的自由度和隐私保护。无论是客户端到服务器的交互,还是服务器到服务器的消息传递,ActivityPub 都为构建去中心化的社交网络提供了强大的工具。

    参考文献

    通过了解和实现 ActivityPub,我们可以构建一个更加自由和开放的互联网社交网络环境。

    image.png

  • ActivityPub:构建分布式社交网络的开放协议

    什么是ActivityPub

    ActivityPub是一种开放的、基于分布式社交网络的协议,用于创建、更新和删除内容,并实现服务器之间的通信和内容传递。它为客户端到服务器和服务器到服务器提供了API接口,使得用户可以方便地在不同的社交网络平台之间进行交流和互动。

    ActivityPub的目标是构建一个去中心化的社交网络,让任何人都可以在网络上运行自己的节点,并与其他服务器上的用户进行关注、点赞、评论等互动。这种去中心化的架构使得用户可以更好地掌控自己的数据和隐私,并且不受单一平台的限制。

    ActivityStreams:社交网络的共同词汇

    ActivityPub使用ActivityStreams作为其词汇,它包含了表示社交网络中各种活动和内容的常用术语。ActivityStreams的词汇已经包含了大部分我们在社交网络中需要使用的词汇,但即使它没有覆盖到我们所需的所有情况,我们仍然可以通过扩展JSON-LD来自定义新的词汇。

    JSON-LD是一种用于表示语义数据的JSON扩展格式,它可以将数据组织成图形结构,并提供了一种机制来连接不同的数据源。对于了解JSON-LD的人来说,可以采取更加高级的链接数据方法;而对于不熟悉JSON-LD的人来说,JSON-LD文档和ActivityStreams可以被理解为普通的JSON格式。通过使用JSON-LD,我们可以更好地描述和表示社交网络中的各种活动和内容。

    ActivityPub的工作原理

    在ActivityPub中,用户通过其在服务器上的帐户来表示为”actors”,每个帐户对应一个独立的”actor”。每个”actor”都有自己的收件箱(inbox)和发件箱(outbox),用于接收和发送消息。用户可以在发件箱中发布消息,其他用户可以通过收件箱接收到这些消息。服务器之间也可以相互传递消息和内容,以实现跨服务器的互联互通。

    举个例子,假设我们有两个用户Alyssa和Ben,他们分别在不同的服务器上拥有自己的帐户。当Alyssa想给Ben发送一条消息时,她会将消息发布到自己的发件箱中。然后,Alyssa的服务器会查找Ben的收件箱地址,并将消息发送到Ben的收件箱中。Ben可以通过检查自己的收件箱来读取Alyssa发送的消息。

    此外,ActivityPub还支持用户之间的关注、点赞、评论等互动。用户可以关注其他用户的帐户,以便在自己的收件箱中接收他们的消息。用户还可以对其他用户的帖子进行点赞或评论,这些互动也会通过服务器之间的通信进行传递。

    ActivityPub的工作进展

    ActivityPub协议是世界广泛支持的社交网络标准,在Fediverse中得到了广泛应用。该标准由Evan Prodromou(StatusNet的创始人)等人共同编写,并于2018年1月被W3C发布为推荐标准。

    ActivityPub的独特之处在于它允许用户在不同的服务器上创建帐户,并与其他服务器上的用户进行互动。这种联邦架构使得用户可以选择自己喜欢的服务器,并与其他用户跨服务器进行关注、点赞、评论等互动。

    目前,许多社交网络平台已经实现了ActivityPub协议,包括Mastodon、PeerTube、Pixelfed等。这些平台都允许用户在自己的服务器上创建帐户,并与其他平台上的用户进行互动。用户可以通过关注其他用户的帐户,接收他们的消息和更新。他们还可以在自己的发件箱中发布消息,使其可供其他用户阅读和互动。

    此外,ActivityPub还支持用户之间的私信功能。用户可以通过私信功能与其他用户进行一对一的私密对话,这些对话只有双方能够看到。

    ActivityPub的应用案例

    Mastodon是基于ActivityPub协议构建的一个开源微博平台,类似于Twitter。用户可以在Mastodon上创建自己的帐户,并与其他用户进行关注、点赞、评论等互动。Mastodon的一个独特之处在于它由许多独立的服务器组成,这些服务器之间通过ActivityPub协议进行通信,用户可以选择加入任何一个服务器。

    PeerTube是基于ActivityPub协议构建的一个开源视频分享平台,类似于YouTube。用户可以在PeerTube上上传和分享视频,并与其他用户进行互动。PeerTube的联邦架构允许用户自主选择他们信任的服务器,并在不同的服务器之间共享视频内容。

    Pixelfed是基于ActivityPub协议构建的一个开源图片分享平台,类似于Instagram。用户可以在Pixelfed上上传和分享图片,并与其他用户进行互动。Pixelfed的联邦架构使得用户可以选择他们喜欢的服务器,并与其他服务器上的用户进行互动。

    ActivityPub的未来发展

    随着ActivityPub协议的不断发展和完善,越来越多的社交网络平台将采用这一标准。这将促进不同平台之间的互操作性和联邦互联,使用户能够更加自由地选择他们喜欢的平台,并与不同平台上的用户进行交流和互动。

    未来,我们可以期待更多创新和发展,例如更加智能化的内容推荐算法、更加灵活的隐私设置以及更加丰富的互动功能。ActivityPub将继续推动社交网络的去中心化和用户自主性的发展,为用户提供更加丰富、安全和自由的社交网络体验。

    参考文献:

    1. ActivityPub – Wikipedia
  • JBang:安装应用程序

    引言

    JBang是一款功能强大的工具,它不仅可以管理依赖项,还可以安装和管理应用程序。通过安装应用程序,我们可以轻松地将脚本和应用程序添加到系统的PATH中,从而在任何操作系统上都可以随时随地调用它们。本文将介绍如何使用JBang安装和管理应用程序。

    安装应用程序

    从版本0.56开始,JBang具备了使用jbang app命令将脚本和应用程序安装到系统的PATH中的功能。这对于在任何操作系统上轻松访问脚本和应用程序非常有用。

    要开始使用,请运行jbang app setup命令。在Windows上,这将修改系统范围的PATH,以包含由JBang管理的文件夹。在基于bash/zsh的shell上,它将在你的bashrc或zshrc文件中设置PATH。

    一旦设置完成,你就可以使用jbang app install <scriptRef>命令将脚本或应用程序安装到JBang管理的路径中。例如,jbang app install myscript.java将把myscript作为一个可以运行的命令。

    你还可以使用别名,例如jbang app install gavsearch@jbangdev

    如果你有两个同名的脚本或应用程序,或者想要使用特定的名称,可以使用--name参数来控制生成的命令,例如jbang app install --name mvnsearch gavsearch@jbangdev

    如果想查看已安装的应用程序列表,可以使用jbang app list命令。如果想卸载脚本或应用程序,可以使用jbang app uninstall <name>命令。

    导出应用程序

    JBang还提供了导出应用程序的功能。通过导出应用程序,你可以将脚本和应用程序打包成可执行的JAR文件,以便在其他环境中运行。导出应用程序非常有用,特别是当你想与其他人共享你的脚本或应用程序时。

    模板

    JBang还支持使用模板来快速创建脚本和应用程序。模板是预先定义好的代码结构和文件布局,你可以根据需要选择和使用它们。使用模板可以加快开发速度,并确保项目具有一致的结构。

    结论

    通过JBang的应用程序安装功能,我们可以轻松地将脚本和应用程序添加到系统的PATH中,使其在任何操作系统上都可以随时调用。通过导出应用程序,我们可以打包脚本和应用程序,以便在其他环境中运行。使用模板可以快速创建具有一致结构的项目。

    JBang为我们提供了强大且便捷的工具,使我们能够更好地管理和使用脚本和应用程序。

    参考文献

  • JBang:灵活的文件组织方式

    引言

    在软件开发过程中,良好的文件组织方式对于代码的可读性和可维护性至关重要。文件组织的合理性可以使我们更好地组织代码和资源文件,提高开发效率。本文将介绍一款名为JBang的工具,它提供了灵活的文件组织方式,使我们能够更好地组织和管理项目文件。

    JBang的文件组织方式

    JBang允许我们使用多个源代码文件,并提供了一种简单的方式来组织这些文件。我们可以将多个源文件放置在同一个源代码目录中,甚至可以在一定程度上使用包进行组织。

    以下是一个示例,展示了如何在JBang中使用多个源文件:

    Main.java
    
    import model.Person;
    
    public class Main {
    
        public static void main(String... args) {
            Person p = new Person(args[0]);
            System.out.println("Hello " + p.getName());
        }
    }
    
    model/Person.java
    
    package model;
    
    public class Person {
        String name;
    
        public String getName() {
            return name;
        }
    
        public Person(String n) {
            this.name = n;
        }
    }

    在这个示例中,我们有两个源代码文件:Main.javamodel/Person.javaMain.java文件包含了应用程序的入口点,而model/Person.java文件定义了一个简单的Person类。我们可以通过在命令行中运行jbang Main.java来执行这个应用程序。

    需要注意的是,当多个源文件相互引用时,有些情况下可能会出现问题。例如,如果model.Person引用了util.Generator,则会导致编译错误。此外,由于jbang edit在运行之前必须进行编译,因此它无法识别和处理多个源文件。

    使用多个源文件的高级功能

    从版本0.46开始,JBang提供了更高级的功能,使多个源文件的管理更加灵活。主要的脚本文件定义了所有的依赖项,而我们可以使用//SOURCES <filename>注释将更多的源文件添加到应用程序中。如果包含的源文件中存在//SOURCES注释,那么这些文件也将被递归地添加进来。对于.jsh脚本文件,包含的源文件将按照它们被发现的顺序进行添加,采用深度优先的方式。

    在编译时,列出的文件名将被添加到源文件列表中。

    需要注意的是,目前尚不支持使用*.java样式匹配或在这些.java文件中声明//DEPS或其他JBang配置。目前,这些配置只会被主要的脚本或应用程序所识别。根据反馈,未来将放宽这些限制。

    添加更多资源文件

    如果你想要添加META-INF/application.propertiesMETA-INF/resource.index.html或其他文件到生成的JAR文件中,你可以使用//FILES注释来添加它们。

    //FILES的格式为//FILES <mountpoint>[=<sourcefile>]

    以下是一个示例:

    //FILES resource.properties
    //FILES META-INF/resources/index.html=index.html

    在这个示例中,resource.properties文件将被直接复制,而META-INF/resources/index.html文件的内容将来自于index.html文件。

    所有的位置都需要相对于脚本所在的位置。

    需要注意的是,目前jbang edit和基于HTTP(S)的脚本与//FILES不兼容。

    用于命令行插件的无扩展名/非Java文件

    你可以使用JBang编写命令行插件,例如kubectl、git等。这些插件希望插件能够以<cmd>-<plugin>的方式命名,例如kubectl-myplugin

    针对这种情况,JBang提供了两种方法来使其工作。第一种推荐的方式是使用jbang app install命令,在中间生成一个脚本来避免问题。例如,jbang app install --name kubectl-my-plugin myplugin.java

    第二种方式是利用JBang的自动处理能力,适用于只有一个文件且不需要中间脚本的情况。具体的做法如下:

    • 将文件命名为kubectl-my-plugin,不包含.java.jsh扩展名。
    • JBang会将该文件复制到一个临时目录,并使用短横线命名法将文件名映射为合适的Java类名。

    例如,如果你创建了一个名为kubectl-my-plugin的文件,JBang将会假设实际的类名为KubectlMyPlugin

    需要注意的是,当使用jbang edit时,JBang会创建一个符号链接,使得IDE将其视为普通的驼峰式Java类。

    如果不遵循这种命名模式,将会导致编译错误,因为javac要求公共类和文件名相等。

    此外,针对无扩展名的脚本,你可以在文件开头添加#!注释,以让应用程序识别它作为脚本处理。为了避免编译问题,JBang在编译之前会删除该注释行。

    结论

    JBang提供了灵活的文件组织方式,使我们能够更好地组织和管理项目文件。通过使用多个源文件和注释,我们可以轻松地组织代码结构,并将资源文件添加到生成的JAR中。此外,JBang还允许我们为命令行插件编写无扩展名的文件,并提供了便捷的命名约定。

    合理的文件组织方式有助于提高代码的可读性和可维护性。通过使用JBang的文件组织功能,我们可以更加高效地开发和管理我们的项目。

    参考文献

  • JBang:简单依赖管理工具

    引言

    在软件开发过程中,我们经常需要使用各种各样的库和框架来构建功能强大的应用程序。然而,手动管理这些依赖项可能会变得非常复杂和耗时。在本文中,我们将介绍一款名为JBang的工具,它可以帮助我们轻松管理项目的依赖项。无论你是一名Java开发人员还是对软件开发感兴趣的新手,JBang都将是你的好帮手。

    JBang简介

    JBang是一款基于Java的命令行工具,它提供了一种简单且灵活的方式来管理项目的依赖项。使用JBang,我们可以轻松地指定所需的库和框架,并自动下载和安装它们,而无需手动处理复杂的依赖关系。JBang还提供了许多有用的功能,例如脚本执行、构建项目和编辑代码等。

    安装和使用JBang

    JBang的安装非常简单。你只需前往官方网站(JBang官网)下载适用于你的操作系统的安装包,然后按照说明进行安装即可。

    安装完成后,你可以在命令行中输入jbang命令验证安装是否成功。如果成功,你将看到JBang的版本信息和可用命令列表。

    指定和管理依赖项

    在JBang中,我们可以使用两种方式指定和管理依赖项:使用内联注释或使用外部依赖文件。

    内联注释方式

    使用内联注释的方式非常简单。在你的脚本或代码文件中,你只需在需要引入依赖项的地方添加类似以下的注释:

    //DEPS groupId:artifactId:version

    其中,groupId代表库或框架的组织ID,artifactId代表项目的唯一标识符,version代表所需的版本号。你可以根据需要指定一个或多个依赖项,它们之间用空格分隔。

    以下是一个使用内联注释指定依赖项的示例:

    //DEPS org.apache.logging.log4j:log4j-core:2.14.1
    //DEPS com.google.guava:guava:30.1-jre

    在你运行脚本时,JBang将自动解析并下载所需的库和框架,并将其添加到类路径中,使其可供你的脚本使用。

    外部依赖文件方式

    除了使用内联注释,JBang还支持使用外部依赖文件来管理项目的依赖项。你可以创建一个文本文件(通常命名为dependencies.jsh),并在其中列出所需的依赖项,每个依赖项占一行。以下是一个外部依赖文件的示例:

    org.apache.logging.log4j:log4j-core:2.14.1
    com.google.guava:guava:30.1-jre

    在你的脚本或代码中,你可以使用以下语法来引用外部依赖文件:

    //DEPS {file=path/to/dependencies.jsh}

    JBang将读取外部依赖文件,并自动解析和下载所需的库和框架。

    解析和安装依赖项

    一旦你在脚本或代码中指定了依赖项,JBang将自动解析并下载所需的库和框架。它会检查本地缓存中是否已经存在这些依赖项,如果不存在,就会从远程存储库中下载并安装它们。

    当你第一次运行包含依赖项的脚本时,JBang会显示一个进度条,提示正在解析和下载依赖项。完成后,你就可以开始使用这些库和框架了。

    示例说明

    让我们通过一个简单的示例来演示JBang的使用。假设我们想编写一个使用log4j库进行日志记录的Java程序。

    首先,我们需要在我们的代码中添加对log4j库的依赖。我们可以使用内联注释或外部依赖文件来指定依赖项。以下是在代码中使用内联注释的示例:

    //DEPS org.apache.logging.log4j:log4j-core:2.14.1

    或者,使用外部依赖文件的示例:

    dependencies.jsh:

    org.apache.logging.log4j:log4j-core:2.14.1

    在你的代码中,你可以使用log4j进行日志记录。以下是一个简单的示例:

    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    public class LoggingExample {
        private static final Logger logger = LogManager.getLogger(LoggingExample.class);
    
        public static void main(String[] args) {
            logger.info("This is an info message");
            logger.warn("This is a warning message");
            logger.error("This is an error message");
        }
    }

    在这个示例中,我们首先导入了log4j库的必要类和接口。然后,我们创建了一个名为logger的静态变量,并使用LogManager.getLogger()方法获取日志记录器。最后,我们使用logger记录了不同级别的日志消息。

    当我们运行这个程序时,log4j将根据配置的日志级别将日志消息输出到控制台或其他目标。

    结论

    JBang是一款强大且易于使用的依赖管理工具,它可以帮助我们简化项目的依赖项管理过程。通过使用内联注释或外部依赖文件,我们可以轻松指定所需的库和框架,并自动解析、下载和安装它们。JBang还提供了许多其他功能,例如脚本执行和项目构建等。

    不管你是一名经验丰富的Java开发人员还是一个新手,JBang都会成为你开发过程中的有力助手。使用JBang,你将能够更快地构建功能丰富的应用程序,并在开发过程中更加专注于核心功能的实现。

    参考文献

  • JBang使用指南

    简介

    JBang是一款强大而灵活的工具,为开发者提供了便捷的方式来编写和运行Java代码。它可以处理包含main方法的单个.java文件,也可以处理.jsh文件(用于jshell)。下面我们将详细介绍JBang的安装和使用方法。

    安装

    要使用JBang,首先需要安装它。安装过程非常简单,只需按照以下步骤操作:

    1. 访问JBang官方网站(https://www.jbang.dev/)。
    2. 根据你的操作系统选择对应的安装包进行下载。
    3. 安装完成后,你就可以使用JBang了。

    使用方法

    JBang的使用方法非常灵活,你可以通过以下几种方式来执行Java代码:

    1. 直接运行Java文件:如果你有一个包含main方法的Java文件,你可以使用以下命令来运行它:
       jbang filename.java

    这将直接执行该Java文件,并输出结果。

    1. 执行.jsh文件:如果你有一个.jsh文件(用于jshell),你可以使用以下命令来执行它:
       jbang filename.jsh

    JBang将会将该文件传递给jshell进行处理,并输出结果。

    1. 运行已编译的Jar文件:JBang还支持直接运行已编译的.jar文件。你可以使用以下命令来运行.jar文件:
       jbang filename.jar

    JBang会自动加载并执行该.jar文件。

    依赖关系

    在Java项目中,处理依赖关系是常见的任务。JBang提供了便捷的方式来管理和引入依赖关系。你可以通过在代码文件中添加//DEPS的注释来指定所需的依赖项,JBang会自动下载并加载这些依赖项。例如:

       //DEPS com.example:library:1.0.0

    这将下载并加载名为”com.example:library:1.0.0″的依赖项。

    Java版本

    JBang兼容多个Java版本,你可以根据自己的需要选择合适的Java版本进行编译和运行。如果系统中没有指定的Java版本,JBang会自动下载并使用默认的Java版本。你也可以使用以下命令来指定Java版本:

       jbang --java java_version filename.java

    其中,java_version表示你要使用的Java版本。

    文件组织

    JBang支持帮助你更好地组织和管理项目文件。你可以将相关的代码文件放在一起,以提高代码的可读性和维护性。例如,你可以将所有与数据库操作相关的文件放在一个名为”database”的文件夹中。

    运行和调试

    JBang提供了丰富的运行和调试功能,让你可以更轻松地执行和调试Java代码。你可以使用以下命令来运行和调试代码:

    • 运行代码:
      jbang run filename.java
    • 调试代码:
      jbang debug filename.java

    编辑

    JBang支持代码编辑功能,你可以通过指定编辑器来编辑代码文件,以提高开发效率。你可以使用以下命令来编辑代码:

    jbang edit filename.java

    JBang会打开默认编辑器,并加载指定的代码文件供你编辑。

    导出和发布

    当你的项目完成后,JBang提供了导出和发布的功能。你可以将代码打包成可执行的文件或发布到其他平台上。例如,你可以使用以下命令将代码导出为可执行的Jar文件:

    jbang export filename.java

    JBang会将代码打包成一个可执行的Jar文件,方便你在其他环境中运行。

    依赖项

    在Java项目中,处理依赖关系是非常常见的任务。JBang提供了便捷的方式来管理和引入依赖项。你可以通过在代码文件中添加//DEPS的注释来指定所需的依赖项,JBang会自动下载并加载这些依赖项。例如:

    //DEPS org.apache.commons:commons-lang3:3.12.0
    //DEPS com.google.guava:guava:30.1-jre

    这样,JBang会自动下载并加载”org.apache.commons:commons-lang3:3.12.0″和”com.google.guava:guava:30.1-jre”这两个依赖项。

    Java版本

    JBang兼容多个Java版本,你可以根据自己的需要选择合适的Java版本进行编译和运行。如果系统中没有指定的Java版本,JBang会自动下载并使用默认的Java版本。你也可以使用以下命令来指定Java版本:

    jbang --java java_version filename.java

    其中,java_version表示你要使用的Java版本。

    文件组织

    JBang支持帮助你更好地组织和管理项目文件。你可以将相关的代码文件放在一起,以提高代码的可读性和维护性。例如,你可以将所有与数据库操作相关的文件放在一个名为”database”的文件夹中。

    运行和调试

    JBang提供了丰富的运行和调试功能,让你可以更轻松地执行和调试Java代码。你可以使用以下命令来运行和调试代码:

    • 运行代码:
      jbang run filename.java
    • 调试代码:
      jbang debug filename.java

    编辑

    JBang支持代码编辑功能,你可以通过指定编辑器来编辑代码文件,以提高开发效率。你可以使用以下命令来编辑代码:

    jbang edit filename.java

    JBang会打开默认编辑器,并加载指定的代码文件供你编辑。

    导出和发布

    当你的项目完成后,JBang提供了导出和发布的功能。你可以将代码打包成可执行的文件或发布到其他平台上。例如,你可以使用以下命令将代码导出为可执行的Jar文件:

    jbang export filename.java

    JBang会将代码打包成一个可执行的Jar文件,方便你在其他环境中运行。

    以上是JBang的一些常用功能和使用方法。通过JBang,你可以更便捷地编写和运行Java代码,提高开发效率和代码质量。

    参考文献:
    JBang使用指南

  • 探索 JBang——Java 开发的全新体验

    前言

    Java 开发者们,无论您是学生、教育者还是专业开发人员,您是否曾经希望有一种更简单、更高效的方式来创建、编辑和运行 Java 程序?今天,我们将带您了解一个令人兴奋的工具——JBang。它不仅简化了 Java 应用的开发过程,还提供了丰富的功能和广泛的支持平台。

    什么是 JBang?

    JBang 是一个旨在让学生、教育者和专业开发人员能够轻松地创建、编辑和运行自包含的源代码 Java 程序的工具。借助 JBang,您可以在几乎任何操作系统上无缝地运行 Java 程序,而且无需复杂的设置过程。

    多平台支持

    安装与运行

    JBang 可以安装并运行在 Windows、Linux、macOS、Docker 以及 GitHub Actions 上。此外,它还可以通过 Maven 和 Gradle 插件使用。这意味着无论您使用什么开发环境,都可以轻松集成 JBang。

    无需预装 Java

    如果您的系统上没有安装 Java,JBang 也能自动下载所需的 Java 版本。这极大地简化了初学者的上手过程。

    嵌入式依赖管理

    自动获取依赖

    通过 JBang,您可以直接在源代码中使用 //DEPS group:artifact:version@Grab 注解来自动获取任何依赖项。这使得依赖管理变得前所未有的简单和直接。

    //DEPS org.slf4j:slf4j-api:1.7.30
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class HelloWorld {
        private static final Logger logger = LoggerFactory.getLogger(HelloWorld.class);
    
        public static void main(String[] args) {
            logger.info("Hello, World!");
        }
    }

    JBang AppStore

    JBang 提供了一个 AppStore,您可以在其中找到其他人发布的应用程序,或者将您自己的应用程序发布到一个由 git 支持的 jbang-catalog.json 中。这为开发者提供了一个共享和发现工具的平台。

    发布与发现应用

    通过 JBang AppStore,您可以轻松地发现和使用其他开发者发布的应用程序,也可以发布自己的应用程序供其他人使用。这种共享机制促进了开发者之间的交流和协作。

    IDE 集成

    无论您使用的是 Intellij、Eclipse、Visual Studio Code、Apache Netbeans,还是 vim 和 emacs,JBang 都能轻松集成。它提供了适当的内容辅助和调试支持,使得开发过程更加流畅和高效。

    轻松编辑与调试

    JBang 提供了丰富的编辑和调试支持,让您在熟悉的开发环境中也能享受到 JBang 带来的便利。无论是代码补全、语法高亮还是调试功能,JBang 都能很好地与您的 IDE 集成。

    选择合适的 Java 版本

    JBang 支持从 Java 8 及更高版本的任何 Java 版本。您可以根据项目需求自由选择最合适的 Java 版本,享受最新的语言特性和性能提升。

    灵活的版本支持

    无论是需要使用 Java 8 的老项目,还是想要尝试最新的 Java 版本,JBang 都能满足您的需求。这种灵活性使得 JBang 成为一个非常适合多种场景的工具。

    用户体验

    很多用户都对 JBang 的使用体验表示赞赏。正如 Oliver Weiler 所说:“第一次使用 JBang 的体验真的很棒!你可以感觉到 @jbangdev 是用爱在做这件事!”

    社区反馈

    通过社交媒体和开发者社区,许多用户分享了他们的使用体验和心得。JBang 的用户友好性和强大的功能得到了广泛的认可和赞誉。

    总结

    JBang 为 Java 开发者提供了一种全新的开发体验。无论是简化的依赖管理、多平台支持、无缝的 IDE 集成,还是便捷的 AppStore,JBang 都展示了其强大的功能和极高的可用性。如果您还没有尝试过 JBang,现在就是开始的好时机!

    欲了解更多信息并下载 JBang,请访问 JBang 官方网站


    参考文献:

    JBang 官方网站

  • 在纯Java文件中推理Llama 2

    在现代人工智能领域,推理大型语言模型(LLM)已经成为一个重要的应用场景。GitHub上的项目 mukel/llama2.java 提供了一种使用纯Java代码进行Llama 2推理的简洁实现。本文将详细介绍该项目的背景、构建方法及性能表现。

    背景介绍

    Llama 2是由Andrej Karpathy开发的一个非常简单的LLM推理实现。该项目的Java版本旨在提供教育价值,并用于在JVM上测试和调整编译器优化,特别是针对Graal编译器的优化。这一Java移植版本最初参考了llama2.scala。

    构建与运行

    要构建和运行该项目,您需要Java 21+,特别是其中的MemorySegment mmap-ing功能。以下是具体的构建步骤:

    1. 下载必要的文件: wget https://github.com/karpathy/llama2.c/raw/master/tokenizer.bin wget https://huggingface.co/karpathy/tinyllamas/resolve/main/stories15M.bin
    2. 手动构建与运行: javac --enable-preview -source 21 --add-modules=jdk.incubator.vector Llama2.java java --enable-preview --add-modules=jdk.incubator.vector Llama2 stories15M.bin
    3. 使用JBang直接运行: jbang Llama2.java stories15M.bin
    4. 使用Makefile和run.sh脚本: make # 可选,run.sh已经包含了make JAVA_HOME=$GRAALVM_HOME \ JAVA_RUNTIME_OPTIONS=-Djava.util.concurrent.ForkJoinPool.common.parallelism=8 \ ./run.sh stories15M.bin

    生成本地镜像

    使用GraalVM可以创建一个独立的本地镜像:

    JAVA_HOME=$GRAALVM_HOME NATIVE_IMAGE_OPTIONS="-march=native" make native-image
    ./llama2 stories15M.bin

    或者使用Profile-Guided Optimizations (PGO):

    JAVA_HOME=$GRAALVM_HOME \
    NATIVE_IMAGE_OPTIONS="--pgo-instrument -march=native --initialize-at-build-time=Llama2 -Dllama2.VectorAPI=false" \
    make native-image
    
    # 生成默认的iprof配置文件
    ./llama2 -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 stories15M.bin
    
    # 构建优化后的镜像
    JAVA_HOME=$GRAALVM_HOME \
    NATIVE_IMAGE_OPTIONS="--pgo -march=native --initialize-at-build-time=Llama2 -Dllama2.VectorAPI=false" \
    make native-image
    
    # 优化后的运行速度应该比普通镜像快约2倍
    ./llama2 stories15M.bin

    性能表现

    以下是该项目在不同配置下的性能测试结果(基于AMD Ryzen 3950X 64GB,Arch Linux):

    单线程测试

    模型每秒处理Token相对于llama2.c的加速实现
    stories15M.bin3631.0llama2.c
    stories15M.bin2370.65llama2.java
    stories110M.bin51.711.0llama2.c
    stories110M.bin42.200.81llama2.java
    llama2_7B.bin0.921.0llama2.c
    llama2_7B.bin0.880.95llama2.java

    多线程测试

    模型每秒处理Token相对于llama2.c的加速实现
    stories15M.bin12331.0llama2.c
    stories15M.bin4380.35llama2.java
    stories110M.bin901.0llama2.c
    stories110M.bin800.88llama2.java
    llama2_7B.bin1.681.0llama2.c
    llama2_7B.bin1.650.98llama2.java

    需要注意的是,Java版本在多线程情况下的性能提升并不显著,这主要是由于内存带宽限制所致。

    结论

    mukel/llama2.java项目展示了如何使用纯Java代码实现Llama 2推理,并在一定程度上达到了与原始C实现相当的性能。尽管当前版本的性能尚未完全优化,但其作为教育工具和编译器优化测试平台已经展现出巨大潜力。

    参考文献:GitHub – mukel/llama2.java

  • 探索 Llama 3 在 Java 中的实际应用

    引言

    在现代人工智能领域,模型推理的效率和方便性是技术人员关注的核心问题。如今,我们将目光投向一个名为 Llama 3 的项目,该项目旨在在 Java 环境中实现 Llama 3 的推理。这一项目不仅是其前身 Llama2.java 的延续,还在多个方面进行了优化和改进。让我们深入了解这个项目的细节及其实现方法。

    项目背景

    Llama 3 是基于 Andrej Karpathy 的 llama2.c 项目的一个扩展版本。Llama3.java 通过单个 Java 文件实现了 Llama 3 的推理,除了教育价值外,还为在 JVM 上测试和调整编译器优化和功能提供了便利,特别是针对 Graal 编译器的优化。

    项目特点

    1. 单文件实现,无依赖

    Llama3.java 的一大特点是其实现是通过单个 Java 文件完成的。这种设计简化了项目的依赖管理,使得项目的部署和维护更加便捷。

    2. 支持多种量化格式

    项目支持 GGUF 格式解析,并且提供了对 Q8_0 和 Q4_0 量化的支持。Q4_0 量化模型由于其较小的体积和较高的运行效率,成为推荐使用的模型。

    3. 高效的矩阵-向量乘法

    针对量化张量,项目使用了 Java 的 Vector API 实现了快速的矩阵-向量乘法。这一实现提高了推理的运行速度,特别是在处理大规模数据时。

    4. 简单的命令行界面

    Llama3.java 提供了一个简单的命令行界面,支持 --chat--instruct 模式,使用户能够方便地与模型进行交互。

    项目设置与运行

    下载量化模型

    首先,需要从 Hugging Face 下载纯 Q4_0 和(可选的)Q8_0 量化的 .gguf 文件。推荐使用大约 4.3GB 的 Q4_0 量化模型:

    curl -L -O https://huggingface.co/mukel/Meta-Llama-3-8B-Instruct-GGUF/resolve/main/Meta-Llama-3-8B-Instruct-Q4_0.gguf
    
    # 可选地下载 Q8_0 量化模型(约 8GB)
    # curl -L -O https://huggingface.co/mukel/Meta-Llama-3-8B-Instruct-GGUF/resolve/main/Meta-Llama-3-8B-Instruct-Q8_0.gguf

    手动量化

    如果需要生成纯 Q4_0 量化模型,可以使用 llama.cpp 提供的量化工具从高精度的 .gguf 源文件生成:

    ./quantize --pure ./Meta-Llama-3-8B-Instruct-F32.gguf ./Meta-Llama-3-8B-Instruct-Q4_0.gguf Q4_0

    构建与运行

    Llama3.java 需要 Java 21 及以上版本,特别是 MemorySegment mmap-ing 功能。可以使用 jbang 工具运行:

    jbang Llama3.java --help

    或者直接执行:

    chmod +x Llama3.java
    ./Llama3.java --help

    使用 Makefile 手动构建

    项目提供了一个简单的 Makefile,可以运行 make 来生成 llama3.jar:

    javac -g --enable-preview -source 21 --add-modules jdk.incubator.vector -d target/classes Llama3.java
    jar -cvfe llama3.jar com.llama4j.Llama3 LICENSE -C target/classes .

    生成的 jar 文件可以如下运行:

    java --enable-preview --add-modules jdk.incubator.vector -jar llama3.jar --help

    性能评估

    在不同的硬件配置下,Llama3.java 的性能表现如下:

    笔记本电脑 Intel 13900H

    模型tokens/s实现
    Llama-3-8B-Instruct-Q4_0.gguf7.53llama.cpp
    Llama-3-8B-Instruct-Q4_0.gguf6.95llama3.java
    Llama-3-8B-Instruct-Q8_0.gguf5.16llama.cpp
    Llama-3-8B-Instruct-Q8_0.gguf4.02llama3.java

    工作站 AMD 3950X

    模型tokens/s实现
    Llama-3-8B-Instruct-Q4_0.gguf9.26llama.cpp
    Llama-3-8B-Instruct-Q4_0.gguf8.03llama3.java
    Llama-3-8B-Instruct-Q8_0.gguf5.79llama.cpp
    Llama-3-8B-Instruct-Q8_0.gguf4.92llama3.java

    结论

    Llama3.java 在 Java 环境中实现了高效的 Llama 3 模型推理,其单文件实现和简单的命令行界面使其具有很高的实用性。虽然在某些性能指标上与 llama.cpp 存在差距,但其在 Java 生态系统中的表现依然值得肯定。

    参考文献

  • 谷歌投资20亿美元在马来西亚建设数据中心及云区域

    根据马来西亚政府的宣布,美国科技巨头谷歌计划在马来西亚投资20亿美元,建设谷歌在该国的首个数据中心和谷歌云区域,同时推进人工智能领域的发展。这一投资使谷歌成为东南亚地区最新一家注入资金以寻求增长机会的科技巨头[1]

    以下是有关这一投资的详细信息:

    1. 投资规模:谷歌将投资20亿美元(约合27亿新元)在马来西亚建设数据中心和云区域[1]
    2. 地点:数据中心和云区域将建在马来西亚雪兰莪州沙亚南的艾美娜商业园[1]
    3. 经济影响:这项投资预计将为马来西亚医疗保健、教育和金融领域提供2万6500个工作机会,并为制造业和服务业利用人工智能和其他先进技术提升全球价值链,创造约150亿4000万令吉(约43亿1600万新元)的经济总值[1]
    4. 谷歌的战略合作:这项投资是建立在谷歌与马来西亚政府合作推进“云优先政策”的基础上的,包括推动一流的网络安全标准[1]

    此外,谷歌的母公司Alphabet及谷歌的总裁兼首席投资官波拉特表示,这是谷歌在马来西亚运营13年来数额最大的投资计划,也是首次在该国设立数据中心和谷歌云区域[1]

    这项投资计划进一步证明了马来西亚政府的明确规划、国家的经济实力和资源,成功吸引了现有和新的投资者,有助于加速马来西亚的数码转型议程[1]


    Learn more:

    1. 谷歌投资20亿美元在马国建数据中心及云区域 | 联合早报
    2. 谷歌将在马来西亚投资 20 亿美元:建数据中心 / 进一步开发 AI,拟创造 2.65 万个就业岗位 – IT之家
    3. 团结政府拼经济奏效 谷歌投资大马94亿! – DAP
  • autoMate:用AI简化你的数字生活

    引言

    在这个数字化飞速发展的时代,我们的生活越来越依赖于各种软件和应用程序。但是,你有没有想过,如果这些软件能够更加智能,能够理解我们的指令并自动完成一些重复性的任务,那将会怎样?这就是autoMate所承诺的——它就像出行中的共享单车一样,只需3分钟,就能将AI的智能植入到任意一个软件中,让你的数字生活变得更加轻松和高效。

    autoMate是什么?

    autoMate是一个开源免费的项目,它允许用户通过简单的配置,将AI的能力集成到他们日常使用的软件中。无论是自动化工作流程,还是简化复杂的任务,autoMate都能提供强大的支持。

    如何开始使用autoMate?

    如果你是第一次使用autoMate,你只需要进行一些基础的设置。首先,你需要修改配置文件,添加OpenAI的信息。这可以通过在autoMate的左上角点击文件,然后选择components,接着配置OpenAI的相关信息来完成。

    autoMate的主要功能

    autoMate的核心功能是将AI集成到软件中,但它并不止步于此。以下是autoMate的一些主要功能:

    • 自动化任务:autoMate可以帮助你自动化那些重复性高且耗时的任务。
    • 智能决策:通过集成AI,autoMate能够提供智能的决策支持,帮助你更高效地完成工作。
    • 易于配置:即使是没有编程背景的用户,也能够通过简单的配置快速上手autoMate。

    各产品优势对比

    autoMate在众多自动化工具中脱颖而出,它的优势在于其开源免费的特性,以及对AI能力的集成。这使得autoMate不仅能够帮助个人用户提高效率,也能够为企业提供强大的自动化解决方案。

    开源社区的支持

    autoMate完全依赖于开源社区的支持,这意味着它不断地在改进和更新。社区的贡献者们不断地为autoMate添加新功能,修复bug,确保它能够满足用户的需求。

    结语

    autoMate是一个强大的工具,它能够让你的软件更加智能,让你的工作更加高效。无论你是希望简化日常任务,还是想要探索AI的潜力,autoMate都是一个值得尝试的选择。而且,由于它是开源免费的,你没有任何理由不试试这个能够改变你数字生活的神奇工具。

    呼吁行动

    如果你对autoMate感兴趣,不妨访问它的GitHub页面,那里有详细的安装指南和使用文档。同时,如果你觉得autoMate对你有帮助,不妨给它点个star,以示对开源项目的支持和鼓励。


  • 一群中国年轻人的留学之路:机会变窄了?

    中国年轻人面临的留学困境

    近年来,越来越多的中国年轻人希望出国留学,追求更广阔的学术和职业发展机会。然而,他们发现出国留学的路越来越窄了。无论是申请奖学金还是签证审查,都面临着越来越多的困难。

    根据《知识分子》援引的一些个人经历,中国学生在申请奖学金时往往发现,他们感兴趣的领域在美国是最发达、最前沿的,但由于种种原因,申请到这些实验室的机会变得非常有限。很多国家也开始提高留学生的审查门槛,一些大学和研究机构参与其中。

    除了奖学金申请的困难,学生还面临着签证审查的问题。有些学生被要求进行安全调查,有的甚至中途被退学。签证审查的时间也越来越长,有的甚至需要等待数年。一些学生在境外留学期间甚至遭遇了盘查和审问,他们的个人隐私和学术资料都受到了审查。

    影响学术发展和人生规划

    这些限制和审查对中国年轻学者的学术发展和人生规划产生了负面影响。一些学者发现,他们无法在自己感兴趣的领域进行研究,一些合作项目也因为政治原因受阻。年轻学者在面对地缘政治的变化时往往处于不利地位,他们可能未能完成必要的国际学术交流和社会资本积累。

    这种局面不仅对留学生产生了影响,也对学术界和科研领域造成了破坏。一些教授和学者因政策变化而受到限制,一些高校面临着来自政府和舆论的压力,导致学术交流受到新的审查。一些高校的部门甚至不得不考虑降低招收学生的标准。

    选择的困境和趋势

    中国年轻学生在面对这些困境时,不得不重新考虑自己的选择。越来越多的学生选择放弃美国,转向其他国家或选择在国内继续深造。一些学生认为,在国内的顶尖高校能够提供更好的学术机会和资源,而且能与家人更加接近。同时,一些国家如新加坡也成为留学的热门目的地。

    然而,这种趋势也引发了一些担忧。一些学者认为,这些限制和审查可能导致学术竞争的不公平,一些领域的学术发展受到了阻碍。年轻学者可能无法获得必要的国际学术交流和社会资本积累,影响了他们的学术发展。

    结论

    中国年轻人出国留学的机会正在变得越来越窄。越来越多的学生面临奖学金申请的困境,签证审查的挑战,以及学术发展受阻的问题。这对年轻学者的学术规划和人生选择带来了负面影响。

    然而,我们也不能忽视这种困境中的机遇。在选择留学的时候,学生们需要更加灵活和机智,寻找适合自己的机会和发展路径。虽然某些国家的机会变少了,但其他一些国家和地区仍然提供了良好的学术环境和机会。同时,在国内的顶尖高校也能够提供丰富的学术资源和发展机会。

    无论面对怎样的困境,年轻学者们应该保持积极的心态,并寻找适合自己发展的道路。学术领域的发展和人生规划需要时间和努力,即使面临困难,也要坚持追求自己的梦想。

    参考文献:

    1. 苏惟楚, 严胜男, 冀思宇. “一种生活]一群中国年轻人的亲身经历:出国留学的路,越来越窄了”. 喷嚏小乖, 2024, 5月9日.
    2. 张紫薇. “中国留学生出国交流遇阻,越来越窄的机会”. 知识分子, 2024.