新增
文章 Jeff Liu · 11 小时 前 8m read

引言 - ObjectScript 中的人工智能流问题

今天,我想介绍一下我在将 AI API 集成到 ObjectScript 应用程序时遇到的一个问题以及找到的解决方案。我最初的测试很成功,但也有些令人沮丧。

HTTP 调用成功了;请求正确地发送到了我的 LLM API。但随后,沉默......漫长的等待。最终,整个响应以单个块的形式到达。

从技术上讲,它成功了,但与 ChatGPT 会话相比,用户体验令人失望。

现代模型设计为逐个令牌流式输出。这使得等待时间大大缩短,因为即使尚未生成完整的答案,您也可以开始读取响应。 要启用此行为,只 需向 API传递 stream=true。 不过,在这种看似简单的操作背后有一个重要的细节:流媒体依赖于服务器发送事件(Server-Sent Events,SSE)。

如果不支持客户端 SSE,就无法利用这种模式。

对于通常在 ObjectScript 中使用的 %Net.HttpRequest 类,响应会被缓冲,直到连接关闭。换句话说,没有增量读取,没有渐进标记,因此也就没有流。

如果我们希望将 LLM 集成到 IRIS 应用程序中,那么能够处理 文本/事件 流、即时解析事件和实时处理数据是至关重要的

0
0 6
InterSystems Developer Community is a community of 26,853 amazing developers
InterSystems IRIS 程序员可以在这里学习、分享、了解最新动态、成长,以及收获快乐!
新增
文章 Kelly Huang · 五月 7 5m read

持续训练(CT)流水线将基于特定时间点可用数据,通过数据科学实验开发出的机器学习(ML)模型规范化。它不仅为模型部署做好准备,还支持在新数据可用时进行自主更新,同时具备用于审计目的的稳健性能监控、日志记录和模型注册功能。

InterSystems IRIS 已经提供了支持此类流水线所需的几乎所有组件。然而,缺少一个关键要素:标准化的模型注册工具。在本文中,我将介绍一种结合 IRIS 优势与开源 AI 工程平台 MLflow 的方法。它们共同作为构建有效持续训练(CT)流水线的互补工具。

本仓库中的实现利用了 MLflow 的内置配置来存储 SHAP 解释器,以提供对相应模型预测结果的解释,包括随机森林(Random Forest)、XGBoost、神经网络等“黑盒”复杂模型。

**演示视频**:https://youtu.be/qLdc4jhn83c

---

CT 流水线组件

该 CT 流水线模块背后的理论基于 Google 在相关文章中定义的 MLOps 1 级行业标准。每个组件的实现都利用了 IRIS 和 MLflow 的最佳特性(如下图所示,红色部分突出显示):

对于那些刚接触 CT 流水线的人来说,上图描述了数据科学项目中传统的实验阶段(上半部分“实验/开发/测试”,通常在 Jupyter Notebook 中进行)如何转化为生产级模型部署。

0
0 6
新增
文章 Lilian Huang · 五月 6 2m read

如果您有长时间运行的报文,这里有一段简单的代码可以捕获它们。您也可以使用队列等待警报(Queue Wait Alert)来获得相同的结果,不过这段代码甚至可以捕获队列为空的单条活动消息。它还能扫描所有命名空间,且不会对生产进行修改,因此可用于调试。

Include Ensemble

Class User.LongMessagesTask Extends %SYS.Task.Definition
{

Parameter TaskName = "Long running messages";

Property LongRunningMessageThreshold As %Integer(MINVAL = 1) [ InitialExpression = 60 ];

Method OnTask() As %Status
{
	set ts = $zdatetime($NOW(0),3,1)
	set ns = ""
	while 1 {
		// Iterate namespaces
		set ns = $o($$$EnsJobMonitorRoot(ns))
		quit:ns=""
		
		set job =""
		while 1 {
			// Iterate jobs
			set job = $o($$$EnsJobMonitorRoot(ns, job))
			quit:job=""
			
			// Get business host name
			set bh = $o($$$EnsJobMonitorRoot(ns,job,""))
			
			// Get the time of the last state change
			set lastActivity = $$$EnsJobMonitorRoot(ns,job,bh,"%LastActivity")
			
			// Get active message, if any - bh can be just idling
			set active = $d(^[ns]Ens.ActiveMessage(job),messageid) // From $$$EnsActiveMessage
			if active {
				set time = $system.SQL.Functions.DATEDIFF("s", lastActivity,  ts)
				if time > ..LongRunningMessageThreshold {
					set text = $$$FormatText("Long running message %1, in ns: %2, BH: %3, processing since %4, for %5 seconds", messageid, ns, bh, lastActivity, time)
					// For debug
					// write text, !
					do ##class(%SYS.System).WriteToConsoleLog(text)
				}
			}
		}
	}
	quit $$$OK
}

}
0
0 4