新しい投稿

Rechercher

質問
· 2024年10月28日

Business Process - Export Code with different versions

Our TEST environment and PROD environment are on two different versions of HealthShare Health Connect.

TEST IRIS for UNIX (Red Hat Enterprise Linux 8 for x86-64) 2024.1 (Build 267_2U) Tue Apr 30 2024 16:06:39 EDT [HealthConnect:7.2.0-1.r1]
PROD IRIS for UNIX (Red Hat Enterprise Linux 8 for x86-64) 2022.1.4 (Build 812_0_22913U) Thu Dec 7 2023 17:06:30 EST [HealthConnect:3.5.0-1.m1] [HealthConnect:3.5.0-1.m1]

Someone within the group wants to migrate a BP from TEST to PROD, however they are running into an error "attribute 'languageOverride' is not declared for element 'assign'" 

I know when we were moving from 2018 to 2022.1.4 there was a command we had to call to format the exports correctly because of the different versions of HealthShare Health Connect. 

  • Is this the same case here?
    • Can someone remind me what that command is?
  • Or how do we get around this error when moving code from a newer version to an older version?
4 Comments
ディスカッション (4)3
続けるにはログインするか新規登録を行ってください
記事
· 2024年10月28日 2m read

Écriture d'une fonction d'agrégation définie par l'utilisateur dans IRIS - exemple : Median

Les fonctions d'agrégation définies par l'utilisateur sont prises en charge dans IRIS depuis 2021.1.0. J'avais souhaité une étoile pour celle-ci il y a des années avant de trouver un moyen secret et astucieux de remplacer MAX et MIN dans un type de données personnalisé, mais je n'ai pas eu l'occasion d'en essayer un jusqu'à aujourd'hui. J'ai pensé que c'était une expérience/un exemple intéressant - la question de savoir comment obtenir une médiane dans IRIS SQL s'est déjà posée une fois - donc je la partage ici sans trop de commentaires supplémentaires.

Une mise en garde : les UDAF n'ont pas la belle parité objet/SQL que les autres types de fonctions ont, vous devez donc exécuter SQL pour définir la fonction d'agrégation (utilement enveloppée dans une méthode de classe dans l'exemple ci-dessous). La compilation de la classe seule ne suffit pas.

/// Classe implémentant une fonction d'agrégation médiane pour IRIS SQL
Class DC.Demo.Median
{

/// Renvoie une nouvelle référence globale dans IRISTEMP à utiliser pour stocker les résultats intermédiaires
ClassMethod Initialize() As %String [ PublicList = ref, SqlProc ]
{
    New ref
    Set ref = $Name(^IRIS.Temp.UDAF.Median($Increment(^IRIS.Temp.UDAF.Median)))
    Set @ref = 0
    Quit ref
}

/// Met à jour la valeur globale temporaire pour un seul enregistrement
ClassMethod Iterate(ref As %String, value As %Numeric) As %String [ SqlProc ]
{
    If (value '= "") {
        Do $Increment(@ref)
        Do $Increment(@ref@(+value))
    }
    Quit ref
}

/// Trouve la médiane réelle (éventuellement une moyenne des deux valeurs médianes)
ClassMethod Finalize(ref As %String) As %Numeric [ SqlProc ]
{
    Set median = ""
    Set total = @ref
    Set position1 = (total+1)\2
    Set position2 = (total+2)\2
    Set val1 = ""
    Set val2 = ""
    Set reached = 0
    Set key = ""
    For {
        Set key = $Order(@ref@(key),1,refCount)
        Quit:key=""
        set reached = reached + refCount
        if (reached >= position1) && (val1 = "") {
            Set val1 = key
        }
        if (reached >= position2) && (val2 = "") {
            Set val2 = key
        }
        If (val1 '= "") && (val2 '= "") {
            Set median = (val1+val2)/2
            Quit
        }
    }
    Kill @ref
    Quit median
}

/// Pour définir réellement l'UDAF d'un point de vue SQL, appelez cette méthode de classe.
ClassMethod Define()
{
    // Supprimez la fonction au cas où quelque chose aurait changé
    &sql(DROP AGGREGATE DC_Demo.Median)
    &sql(CREATE AGGREGATE DC_Demo.Median(arg NUMERIC) RETURNS NUMERIC
       INITIALIZE WITH DC_Demo.Median_Initialize
       ITERATE WITH DC_Demo.Median_Iterate
       FINALIZE WITH DC_Demo.Median_Finalize)
    $$$ThrowSQLIfError(SQLCODE,%msg)
}

}

J'espère que cela aidera quelqu'un !

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください
記事
· 2024年10月28日 4m read

Modelos LLM e Aplicações RAG Passo a Passo - Parte I

Você provavelmente já ouviu falar muito sobre LLMs (Large Language Models) e o desenvolvimento associado de aplicações RAG (Retrieval Augmented Generation) no último ano. Bem, nesta série de artigos explicaremos os fundamentos de cada termo usado e veremos como desenvolver uma aplicação RAG simples.

O que é um LLM?

Modelos LLM fazem parte do que conhecemos como IA generativa e sua fundação é a vetorização de enormes quantidades de textos. Por meio dessa vetorização, obteremos um espaço vetorial (desculpe a redundância) em que palavras ou termos relacionados estarão mais próximos uns dos outros do que palavras menos relacionadas

Embora a maneira mais simples de visualizá-lo seja um gráfico 3D como o da imagem anterior, o número de dimensões pode ser tão grande quanto desejado; quanto maiores as dimensões, maior a precisão nas relações entre termos e palavras e maior o consumo de recursos do mesmo

Esses modelos são treinados com conjuntos de dados massivos que permitem que eles tenham informações suficientes para serem capazes de gerar textos relacionados ao pedido feito a eles, mas... como o modelo sabe quais termos estão relacionados à pergunta feita? Muito simples, pela chamada "similaridade" entre vetores, isso não é mais do que um cálculo matemático que nos permite elucidar a distância entre dois vetores. Os cálculos mais comuns são:

Através desse tipo de cálculo, o LLM será capaz de montar uma resposta coerente com base em termos próximos à pergunta feita em relação ao seu contexto.

Tudo isso é muito bom, mas esses LLMs têm uma limitação quando se trata de sua aplicação para usos específicos, já que as informações com as quais foram treinados costumam ser bastante "gerais". Se quisermos que um modelo LLM se adapte às necessidades específicas do nosso negócio, teremos duas opções:

Fine-tuning

O fine-tuning é uma técnica que permite o re treinamento de modelos LLM com dados relacionados a um tópico específico (linguagem procedimental, terminologia médica, etc.). Usando essa técnica, podemos ter modelos mais adequados às nossas necessidades sem precisar treinar um modelo do zero.

A principal desvantagem dessa técnica é que ainda precisamos fornecer ao LLM uma enorme quantidade de informações para tal re treinamento e, às vezes, isso pode ficar "aquém" das expectativas de um determinado negócio.

Retrieval Augmented Generation

RAG é uma técnica que permite que o LLM inclua o contexto necessário para responder a uma determinada pergunta sem precisar treinar ou re treinar o modelo especificamente com a informação relevante.

Como incluímos o contexto necessário em nosso LLM? É muito simples: ao enviar a pergunta para o modelo, diremos explicitamente que ele deve levar em conta a informação relevante que anexamos para responder à consulta feita, e para isso, usaremos bancos de dados vetoriais dos quais podemos extrair o contexto relacionado à pergunta submetida.

Qual é a melhor opção para o meu problema, Fine tuning ou RAG?

Ambas as opções têm suas vantagens e desvantagens. Por um lado, o Fine tuning permite que você inclua todas as informações relacionadas ao problema que deseja resolver dentro do modelo LLM, sem precisar de tecnologias de terceiros como um banco de dados vetorial para armazenar contextos. Por outro lado, ele te prende ao modelo re treinado, e se ele não atender às expectativas do modelo, migrar para um novo pode ser bastante tedioso.

Por outro lado, o RAG precisa de recursos como buscas vetoriais para poder saber qual é o contexto mais exato para a pergunta que estamos passando para nosso LLM. Esse contexto deve ser armazenado em um banco de dados vetorial no qual realizaremos consultas posteriormente para extrair dita informação. A principal vantagem (além de dizer explicitamente ao LLM para usar o contexto que fornecemos) é que não estamos presos ao modelo LLM, podendo trocá-lo por outro mais adequado às nossas necessidades.

Como apresentamos no início do artigo, vamos nos concentrar no desenvolvimento de um exemplo de aplicação em RAG (sem grandes pretensões, apenas para demonstrar como você pode começar).

Arquitetura de um Projeto RAG

Vamos dar uma breve olhada em qual arquitetura seria necessária para um projeto RAG:

Por um lado, teremos os seguintes atores:

  • Usuários: que interagirão com o LLM enviando consultas.
  • Contexto: Fornecido antecipadamente para ser incluído nas consultas do usuário.
  • Modelo de vetorização: para vetorizar os diferentes documentos associados ao contexto.
  • Banco de dados vetorial: neste caso será o IRIS e armazenará as diferentes partes vetorizadas dos documentos de contexto.
  • LLM: Modelo LLM que receberá as consultas, para este exemplo escolhemos o MISTRAL.
  • Aplicação Python: destinada a consultar o banco de dados vetorial para extração de contexto e sua inclusão na consulta LLM.

Para não complicar demais o diagrama, omiti a aplicação responsável por capturar os documentos do contexto, sua divisão e posterior vetorização e inserção. Na aplicação associada você pode consultar esta etapa, bem como a seguinte relacionada à consulta para extração, mas não se preocupe, veremos isso com mais detalhes nos próximos artigos.

Associado a este artigo você tem o projeto que usaremos como referência para explicar cada etapa em detalhe. Este projeto está containerizado no Docker e você pode encontrar uma aplicação Python usando Jupyter Notebook e uma instância do IRIS. Você precisará de uma conta no MISTRAL AI para incluir a API Key que permite lançar consultas.

No próximo artigo veremos como registrar nosso contexto em um banco de dados vetorial. Fique ligado!

1 Comment
ディスカッション (1)2
続けるにはログインするか新規登録を行ってください
質問
· 2024年10月28日

Problem with local (private) IPM registry

I'm trying out the package manager (IPM). I'm trying to create a local (private) registry. To me it looks like the local registry installation succeeded but I can't figure out how to use it.

I'm using latest stable v0.7.3.

I have uploaded one module there (as told in one forum post):

$ curl http://localhost:52774/registry/
{"version":"1.3.2"}
$ curl http://localhost:52774/registry/packages/-/all
[{"name":"objectscript-math","description":"Math library for InterSystems ObjectScript","repository":"https://github.com/psteiwer/ObjectScript-Math/","origin":"","versions":["0.0.5"],"is_owner":0}]

Now trying to use that repository:

zpm:IPMTEST1>list-installed -tree
zpm-registry 1.3.2
└──yaml-utils 0.1.4

zpm:IPMTEST1>repo -list

registry
        Source:                 https://pm.community.intersystems.com
        Enabled?                Yes
        Available?              Yes
        Use for Snapshots?      Yes
        Use for Prereleases?    Yes
        Is Read-Only?           No
        Deployment Enabled?     No

zpm:IPMTEST1>repo -name registry -list-modules
[a long list of modules removed for readability]

zpm:IPMTEST1>repo -name local -remote -url http://localhost:52774/registry/

local
        Source:                 http://localhost:52774/registry/
        Enabled?                Yes
        Available?              No
        Use for Snapshots?      Yes
        Use for Prereleases?    Yes
        Is Read-Only?           No
        Deployment Enabled?     No
zpm:IPMTEST1>repo -list

local
        Source:                 http://localhost:52774/registry/
        Enabled?                Yes
        Available?              No
        Use for Snapshots?      Yes
        Use for Prereleases?    Yes
        Is Read-Only?           No
        Deployment Enabled?     No

registry
        Source:                 https://pm.community.intersystems.com
        Enabled?                Yes
        Available?              Yes
        Use for Snapshots?      Yes
        Use for Prereleases?    Yes
        Is Read-Only?           No
        Deployment Enabled?     No

zpm:IPMTEST1>repo -name local -list-modules

zpm:IPMTEST1>

Why my local repository is not available (Available? No) and why I don't see the objectscript-math module here?

There is also always a significant delay in operations with local repository, like some kind of timeout.

4 Comments
ディスカッション (4)2
続けるにはログインするか新規登録を行ってください
記事
· 2024年10月28日 2m read

Writing a user-defined aggregate function in IRIS - example: Median

User-defined aggregate functions have been supported in IRIS since 2021.1.0. I'd wished upon a star for these years ago before finding a secret hacky way to override MAX and MIN in a custom datatype, but didn't get a chance to actually try one out until today. I thought it was an interesting experience/example - the question of how to get a Median in IRIS SQL came up once before - so I'm sharing it here without too much further comment.

One caveat: UDAFs don't have the nice object/SQL parity that other types of functions do, so you actually need to run SQL to define the aggregate function (helpfully wrapped in a classmethod in the below example). Compiling the class alone isn't enough.

/// Class implementing a Median aggregate function for IRIS SQL
Class DC.Demo.Median
{

/// Returns a new global ref in IRISTEMP to use to store intermediate results
ClassMethod Initialize() As %String [ PublicList = ref, SqlProc ]
{
	New ref
	Set ref = $Name(^IRIS.Temp.UDAF.Median($Increment(^IRIS.Temp.UDAF.Median)))
	Set @ref = 0
	Quit ref
}

/// Updates temp global for a single record
ClassMethod Iterate(ref As %String, value As %Numeric) As %String [ SqlProc ]
{
	If (value '= "") {
		Do $Increment(@ref)
		Do $Increment(@ref@(+value))
	}
	Quit ref
}

/// Finds the actual median (possibly an average of the two middle values)
ClassMethod Finalize(ref As %String) As %Numeric [ SqlProc ]
{
	Set median = ""
	Set total = @ref
	Set position1 = (total+1)\2
	Set position2 = (total+2)\2
	Set val1 = ""
	Set val2 = ""
	Set reached = 0
	Set key = ""
	For {
		Set key = $Order(@ref@(key),1,refCount)
		Quit:key=""
		set reached = reached + refCount
		if (reached >= position1) && (val1 = "") {
			Set val1 = key
		}
		if (reached >= position2) && (val2 = "") {
			Set val2 = key
		}
		If (val1 '= "") && (val2 '= "") {
			Set median = (val1+val2)/2
			Quit
		}
	}
	Kill @ref
	Quit median
}

/// To actually define the UDAF from an SQL perspective, call this classmethod.
ClassMethod Define()
{
	// Drop the function in case something has changed
	&sql(DROP AGGREGATE DC_Demo.Median)
	&sql(CREATE AGGREGATE DC_Demo.Median(arg NUMERIC) RETURNS NUMERIC
	   INITIALIZE WITH DC_Demo.Median_Initialize
	   ITERATE WITH DC_Demo.Median_Iterate
	   FINALIZE WITH DC_Demo.Median_Finalize)
	$$$ThrowSQLIfError(SQLCODE,%msg)
}

}

Hopefully this helps someone!

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください