2024年4月

域名解析中常常涉及:A记录,CNAME,NS

1.
A记录 又称IP指向
,用户可以在此设置子域名并指向到自己的目标主机地址上,从而实现通过域名找到服务器。说明:指向的
目标主机地址类型只能使用IP地址
;

2.
CNAME 通常称别名指向
,您可以为一个主机设置别名。比如设置test.mydomain.com,用来指向一个主机www.rddns.com那么以后就可以用test.mydomain.com来代替访问www.rddns.com了。

3.
解析服务器记录。用来表明由哪台服务器对该域名进行解析
。这里的NS 记录只对子域名生效。例如用户希望由12.34.56.78这台服务器解析news.mydomain.com,则需要设置news.mydomain.com的NS记录。

详细举例如下两幅图:

前言

这个项目是我很早之前就star,只是当时觉得有点天真,怎么会有那么多免费的好事情呢?然后就在清明节前夕,OpenAI 开放了免登录即可使用GPT-3.5的模型,那么势必很快就有了免费使用GPT-3.5接口的开源项目,这里也提供一下我前几天写的文章 有兴趣的可以看看**
# 开源免费、无需注册、一键部署、模拟web轻松无限制使用GPT-3.5 API
**。

当时尝试成功了以后,我就在想GPT-4的免费接口是不是也是真的能用了?于是我就回过头来去查看之前star的项目了。

废话就不继续多说了,直接上开源项目地址:
https://github.com/xtekky/gpt4free

然后查看开源项目readme后,看看有没有最简单的使用方式:docker 部署呢?

通过截图可以发现介绍的非常清晰。不太懂英文的也可以进行翻译一下,或者直接按照我下面的步骤进行安装也是没问题的。

这里要有一个前提哈,就是电脑上要先安装了 docker 的环境。 window 和 mac 以及 linux 上都可以安装 docker ,如果有不明白的地方,可以多问问 GPT 进行安装处理一下,这方面的资料非常多,我就不在此重复了。下面进入正题。

开始安装

// 拉取镜像
docker pull hlohaus789/g4f

安装完通过
docker images
来看看

OK能看到
hlohaus789/g4f
镜像

// 根据镜像运行容器
docker run -p 8080:8080 -p 1337:1337 -p 7900:7900 --shm-size="2g" -v ${PWD}/hardir:/app/hardir hlohaus789/g4f:latest

运行命令后如果能看到如下所示的界面应该就是安装好了

根据上面的图在浏览器上输入:**
http://127.0.0.1:8080/
**

看到这个界面你又成功了一大半了,但更重要的要来了。

开始测试

啊哈,怎么是GPT-3.5呢,这个没用的东西。再来试一次。

我给最顶部添加了系统的
prompt
。然后又问了同样的问题。惊不惊喜,竟然真的是GPT-4大模型了。

如果回答报错了,可以点击下方的
Regenerate
按钮重新生成。 其实还可以下输入框下方来调整模型的。你可以根据开源地址再往下面,会看右侧的提供的可选模型。

最后

如果你是window电脑那么你也可以安装window的exe文件试试。

image.png

这个项目通过一种巧妙的方式工作:它伪装成了chatgpt的官方聊天客户端,或者是其他一些已经向OpenAI付费的网站,比如poe、bing等,然后调用这些网站的接口来间接调用OpenAI的服务。

不得不说这个开源真的付出了很多,不仅仅有GPT-4的免费接口,还包括了Claude3 等等其他大厂的API厂商,真的太棒了

有兴趣的可以研究一下如何调用API呢?通过http://localhost:1337/v1

image.png

通过项目也可以看到其中也实现了类库共外部专门调用

image.png

这是python的版本,有兴趣的话就去试试吧,能免费使用,也顺便给人家来个star表示支持吧。

好了今天的分享就到这里了。

技术背景

这篇文章来源于MindSpore仓库中的一个
Issue
,简单描述问题就是,如果你用MindSpore开发了一个python软件供别人使用,那么很有可能涉及到编译构建的问题。但是如果直接使用编译好的whl包去运行的话,就有可能出现一个跟Jit即时编译有关的报错,这里Jit在其他的一些模块中也会被使用到,比如Vmap函数和Grad函数等。

问题复现

我们通过一个简单的测试案例来复现一下这个RuntimeError。

软件环境

-- MindSpore version: 2.2.11
-- Python version: 3.9.16
-- OS platform and distribution: Linux Ubuntu 20.04

执行模式

GRAPH_MODE

复现代码结构

debug/
├── debug
│   ├── __init__.py
│   └── test_vmap.py
├── example
│   └── test.py
└── setup.py

代码内容

setup.py

from setuptools import setup, find_packages
from pathlib import Path
this_directory = Path(__file__).parent

setup(
    name="debugs",
    version="1.0",
    description="Test Vmap",
    license="Apache 2.0 Licence",
    packages=find_packages(),
    platforms="any",
    scripts=[],
    include_package_data=True
)

test_vmap.py

from mindspore import ops

func = lambda ts: ts
batch_func = ops.vmap(func, in_axes=(0, ), out_axes=(0, ))

test.py

# import sys
# sys.path.insert(0, '../')

from debug.test_vmap import batch_func
from mindspore import Tensor

a = Tensor([0, 1])
batch_a = batch_func(a)
print (batch_a)

复现步骤

  1. 按照目录树结构构建好本地测试复现环境;
  2. 取消test.py文件中的两行注释,运行python3 test.py;
  3. 通过setup.py构建安装python3 setup.py install,然后把test.py文件的头两行注释掉,再次运行python3 test.py。

预期结果

两次运行test.py都输出
[0 1]

报错信息

第一次测试,为了方便代码阅读,使用了lambda函数,后来发现这个报错可能是即时编译跟lambda函数不兼容所导致的:

后来修改成了普通的函数,才复现了一个RuntimeError:

test_vmap.py

from mindspore import ops, jit

@jit
def func(ts):
    return ts

batch_func = ops.vmap(func, in_axes=(0, ), out_axes=(0, ))

得到的报错信息为:

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    batch_a = batch_func(a)
  File "/home/dechin/anaconda3/envs/mindspore-latest/lib/python3.7/site-packages/mindspore/common/api.py", line 718, in staging_specialize
    out = _MindsporeFunctionExecutor(func, hash_obj, input_signature, process_obj, jit_config)(*args, **kwargs)
  File "/home/dechin/anaconda3/envs/mindspore-latest/lib/python3.7/site-packages/mindspore/common/api.py", line 121, in wrapper
    results = fn(*arg, **kwargs)
  File "/home/dechin/anaconda3/envs/mindspore-latest/lib/python3.7/site-packages/mindspore/common/api.py", line 350, in __call__
    raise err
  File "/home/dechin/anaconda3/envs/mindspore-latest/lib/python3.7/site-packages/mindspore/common/api.py", line 344, in __call__
    phase = self.compile(self.fn.__name__, *args_list, **kwargs)
  File "/home/dechin/anaconda3/envs/mindspore-latest/lib/python3.7/site-packages/mindspore/common/api.py", line 435, in compile
    is_compile = self._graph_executor.compile(self.fn, compile_args, kwargs, phase, True)
RuntimeError: 'VmapOperation' arg0 must be a 'Function' or 'Cell', but got AbstractScalar(Type: External, Value: PythonObject(type: <class 'function'>, value: <function func at 0x7f75c0375ef0>), Shape: NoShape).

----------------------------------------------------
- C++ Call Stack: (For framework developers)
----------------------------------------------------
mindspore/ccsrc/frontend/operator/composite/composite.cc:1420 CheckVmapFunc

----------------------------------------------------
- The Traceback of Net Construct Code:
----------------------------------------------------
# 0 In file /home/dechin/anaconda3/envs/mindspore-latest/lib/python3.7/site-packages/mindspore/ops/composite/base.py:686
            return vmap_(fn, in_axes, out_axes)(*args, **kwargs)
                   ^
 (See file '/tmp/debug/example/rank_0/om/analyze_fail.ir' for more details. Get instructions about `analyze_fail.ir` at https://www.mindspore.cn/search?inputValue=analyze_fail.ir)

问题原因

按照开发人员的回复,这个问题是因为Vmap会使用到静态图模式。但是编译成whl包之后,静态图模式下会把whl包的内容识别为第三方仓库。从第三方仓库来的函数,有可能出现无法入图的问题:

解决的方法就是,把相应的仓库添加到环境变量中去:

export MS_JIT_MODULES=debug

然后再次运行test.py,问题就解决了。

总结概要

在MindSpore编译计算图的过程中,会把从编译构建好的whl包中引入的模块视为第三方库,也就没有办法在即时编译的阶段入图。普通的math和numpy等第三方库不入图也不会影响计算。但如果是基于MindSpore本身开发的一些函数,如果用到了Jit、Grad和Vmap,那么有可能出现无法入图的问题,就会出现RuntimeError报错。解决方法就是设置一个跟即时编译有关的环境变量,把相关的第三方包引用修改为内部引用。

版权声明

本文首发链接为:
https://www.cnblogs.com/dechinphy/p/ms_jit_module.html

作者ID:DechinPhy

更多原著文章:
https://www.cnblogs.com/dechinphy/

请博主喝咖啡:
https://www.cnblogs.com/dechinphy/gallery/image/379634.html

Avalonia是一个跨平台的.NET UI框架,它允许开发者使用C#和XAML来创建丰富的桌面应用程序。在Avalonia中,Alignment、Margin和Padding是非常重要的布局属性,它们与Panel元素一起使用,可以构建出各种复杂的用户界面。

Alignment、Margin 和 Padding是什么

  1. Alignment(对齐方式)
    Alignment决定了元素在Panel中的对齐方式。对于每个方向(水平或垂直),都可以设置对齐方式。水平对齐包括Left、Center、Right和Stretch,而垂直对齐包括Top、Center、Bottom和Stretch。Stretch意味着元素将占据可用空间。

  2. Margin(外边距)
    Margin是元素与其相邻元素之间的空间。通过为元素设置Margin,可以控制元素与其周围的元素之间的距离,从而改变整体布局的外观。

  3. Padding(内边距)
    Padding是元素边框与其内容之间的空间。调整Padding的大小可以改变元素内部的空间,使得内容不会过于拥挤或过于空旷。

Alignment、Margin 和 Padding的示例代码

假设我们有一个简单的StackPanel,其中包含几个Button。

var stackPanel = newStackPanel();var button1 = new Button { Content = "Button 1", Margin = new Thickness(5) };var button2 = new Button { Content = "Button 2", Padding = new Thickness(10) };var button3 = new Button { Content = "Button 3", HorizontalAlignment =HorizontalAlignment.Right };  

stackPanel.Children.Add(button1);
stackPanel.Children.Add(button2);
stackPanel.Children.Add(button3);
this.Content = stackPanel;

在这个例子中:

  • button1 设置了Margin,使得按钮与其周围的元素之间有5个单位的距离。
  • button2 设置了Padding,使得按钮内部的文字与其边框之间有10个单位的距离。
  • button3 设置了HorizontalAlignment为Right,使得按钮在其父StackPanel中水平靠右对齐。

常见Panel有哪些

Avalonia提供了多种Panel,每种都有其特定的用途和布局方式:

  • StackPanel:按指定方向(水平或垂直)堆叠子元素。
  • DockPanel:允许子元素停靠在其容器的边缘。
  • Grid:提供表格布局,可以定义行和列来放置子元素。
  • WrapPanel:当空间不足时,子元素会换行或换列。
  • UniformGrid:创建一个固定数量的行和列的网格,所有单元格大小相同。
  • Canvas:允许通过绝对坐标定位子元素。

常见Panel的示例代码

下面是一个简单的Grid Panel的示例代码:

var grid = new Grid { RowDefinitions = new RowDefinitions("Auto,Auto,*"), ColumnDefinitions = new ColumnDefinitions("Auto,Auto") };var button1 = new Button { Content = "Button 1"};var button2 = new Button { Content = "Button 2"};var button3 = new Button { Content = "Button 3", HorizontalAlignment =HorizontalAlignment.Stretch };var button4 = new Button { Content = "Button 4"};

grid.Children.Add(button1);
grid.Children.Add(button2);
Grid.SetRow(button2,
1);
grid.Children.Add(button3);
Grid.SetColumn(button3,
1);
grid.Children.Add(button4);
Grid.SetRow(button4,
1);
Grid.SetColumn(button4,
1);this.Content = grid;

在这个例子中,我们创建了一个Grid,并定义了它的行和列。然后,我们添加了四个按钮,并使用Grid.SetRow和Grid.SetColumn方法将它们放置在特定的单元格中。button3设置了HorizontalAlignment为Stretch,这意味着它将填满其所在列的可用空间。

通过组合使用Alignment、Margin、Padding和不同的Panel,开发者可以在Avalonia中构建出灵活多变且富有吸引力的用户界面。这些属性提供了强大的布局控制能力,使得开发者能够精确控制元素的位置和外观。

1. 背景

应项目需求,本qiang~这两周全身心投入了进去。

项目是关于一个博物馆知识图谱,上层做KBQA应用。
实现要求是将传统KBQA中的部分模块,如NLU、指代消解、实体对齐等任务,完全由LLM实现
,本qiang~针对该任务还是灰常感兴趣的,遂开展了项目研发工作。

注意,此篇是纯纯的干货篇,除了源码没有提供外,整体核心组件均展示了出来。也是这两周工作的整体总结,欢迎大家查阅以及加关注(不强求哈~)

2. 整体框架

整体思想还是遵循RAG策略,从图谱召回候选背景知识,让LLM进行润色回答。

具体的流程如下:

(1) 用户提问
:已发现的体重最大的肉食性恐龙是什么

(2) 对齐模块。

对齐模块的主要作用是针对问题与知识图谱中的实体、概念、关系、属性进行对齐。

其中候选概念、候选属性、候选关系在图谱中的数量是少量有限的,而实体的数量可多可少,因此候选概念、候选属性、候选关系可以在查询hugegraph后,直接拼到对齐prompt中(对齐的prompt预留了占位符),而实体则需要进行预筛选,筛选的方式是通过问题query与实体名进行语义相似度比较,通过语义相似度引擎实现,比如simbert, bge, gte等开源模型,预筛选后的少量实体可以拼接到对齐prompt。

对齐的prompt增加要求和few-shot示例,可以解决常见对齐问题,比如实体、概念、属性、关系存在缺字、多字、相似字等情况。

(3) 对齐模块经过LLM进行对齐,输出对齐结果。

本示例的对齐结果为:(属性-等于-体重)且(属性值-等于-最大); (属性-等于-食性)且(属性值-等于-肉食性);(概念-等于-恐龙)。

(4) 对齐校准模块。

对齐校准模块主要针对LLM对齐结果进行二次校对,解决的问题如下:

1) 一些LLM将概念与实体混淆的情况;

2) 与图谱中的实体、概念、属性、关系进行对齐匹配;

3) 实体名和概念名重复时,二者均进行召回等

(5) 解析及溯源模块

解析模块:

针对校准后的对齐结果,执行解析模块,解析模块会基于对齐结果进行判断,该执行如下哪种解析,候选的解析列表有:纯实体解析、纯概念解析、实体-属性解析、概念-属性解析、属性-属性值解析、属性-属性值-概念解析等。

(Ps: 候选解析列表是分析了大量数据之后,抽象出来的解析列表,常见的问答基本就涵盖在这些列表中)

每个解析模块会有不同的解析逻辑,例如:

1) 纯实体解析:会将查询hugegraph得到的实体作为背景知识提供给LLM,如介绍下霸王龙

2) 纯概念解析:会查询概念下有哪些实体,且仅列出实体名称作为背景知识提供给LLM,如恐龙都有哪些?

3) 实体-属性解析:会查询实体对应的属性或关系,并作为背景知识,如霸王龙有多重多高?

4) 概念-属性解析:会查询概念下实体的属性信息作为背景知识,如恐龙目下动物的体重分别是多少?

5) 属性-属性值解析:会查询属性对应属性值的信息,并作为背景知识,如肉食性的动物有?

溯源模块:主要功能就是从图谱中查询的结果,需要返回图谱对应的实体id、概念id、属性等

6) 问答模块

通过将解析后的背景知识以及用户的问题,经过问答prompt,然后调用LLM进行润色回答。

PS:

对齐prompt调用大模型是非流式输出,因为对齐结果不需要实时同步给用户;

问答prompt调用大模型是流式输出,因为问答结果需要实时同步给用户

3. 优缺点

(1)
优点

1) 整体架构简单,仅需要2个prompt,与LLM仅交互2次

2) 解析模块基于多数据集进行抽象,可覆盖多数查询场景

3) 针对未覆盖的场景,解析模块可支持快速扩展适配

4) 迁移新图谱时,业务只需要更改prompt即可,对业务相对友好

(2)
缺点

1) 首字响应时间主要耗时在对齐prompt与LLM的交互中,因为需要对齐完整输出结果

2) 概念、属性、实体对齐集中在1个prompt中,所以prompt的长度较长

4. 多轮问答实现

实现的思路如下:

1) 缓存历史问题以及缓存历史对齐的实体或概念,如可以缓存最近10轮的用户问题以及对齐结果

2) 针对指代消解、语义对齐prompt调优,且多轮问答的prompt也集成在对齐prompt中(因此,对齐prompt任务十分繁重)

具体示例如下(从对齐prompt截取了部分,第一次输入参考为空):

历史输入信息:

```

输入:盐都龙喜欢吃什么

参考:

输入:喜欢生活在什么地方

参考:盐都龙

输入:三角龙是植食还是肉食

参考:盐都龙

输入:有什么本事

参考:三角龙

输入:普尔塔龙多重

参考:三角龙

```

现在请回答:

输入: 吃什么

参考: 普尔塔龙

输出:

具体的效果可以查阅下面章节中的效果示例。

5. 效果

图谱三元组总量3000+,测试样例共计385条,其中单轮问答340条,多轮问答45条。

(1)
单轮问答效果,准确率93%+

一阶问答

华阳龙的头骨化石是在哪里发现的

华阳龙的头骨化石是在中国四川省发现的。

判断问答

恐爪龙有4米长吗

恐爪龙的身长是3.5米左右,没有4米。

对比问答

三角龙和姜氏巴克龙谁更重

三角龙更重。

条件问答

化石在四川发现的恐龙有哪些

最大体型的长羽毛恐龙是二连巨盗龙。

组合问答

单爪龙身长体重多少?

单爪龙的身长是1~1.2米,体重约3.5千克。

(2)
多轮问答效果,准确率93%+

1) 示例1:
缺字情况

问:普尔塔多重

答:普尔塔龙的体重是75吨。

问:吃什么

答:普尔塔龙是植食性的

2) 示例2:
错字情况

问:河堤列龙生活在什么地方

答:河堤猎龙生活在英国的怀特岛和奇尔顿岭。

问:它是什么时候的恐龙

答:河堤猎龙是早白垩世,巴雷姆期的恐龙。

3) 示例3:
较困难的指代消解

问:三角龙是植食还是肉食

答:三角龙是植食性的。

问:有啥本事

答:三角龙的能力是快速奔跑。

问:和肿头龙比,谁更长一些?

答:三角龙的身长为8米,而肿头龙的身长为4~6米。因此,三角龙更长一些。

问:那它的体重是多少?

答:三角龙的体重是6.1~12吨。

6. 答疑解惑

(1) 候选实体、候选概念、候选属性如何动态加载至prompt?

解:prompt预留占位符,代码解析时进行格式化

(2) 概念、属性数量有限,可以全部写在prompt,但如果实体有1W个呢?

解:基于sim进行候选实体召回策略

(3) 如何实现流式输出?

解:基于tornado的websocket框架,结合异步框架asyncio以及python的yield、next等方法实现

(4) 非流式调用LLM出现网络不稳定导致超时,如何解决?

解:增加重试机制

(5) 对齐结果如何进一步保障?

解:增加对齐校准模块

(6) 如何减少频繁调用hugegraph

解:预先加载图谱至内存,然后使用python的lru_cache缓存机制

(7) 如何提高属性、概念、实体对齐的准确率,比如多字、缺字、相近字等?

解:对齐prompt增加要求以及few-shot

(8) 如何解决实体文字完全不一致,但指的同一个实体的情况,比如霸王龙和雷克斯暴龙?

解:通过图谱的别名维护,且当前别名与正式名地位相同

(9) 溯源是如何实现的?

解:在每个解析分支中,基于解析结果增加对应图谱的信息

(10) 如何实现最大、最小之类的查询,如体重最大的植食性恐龙是哪个?

解:对齐结果:(属性-等于-体重)且(属性值-等于-最大)且(概念-等于-恐龙)

解析逻辑:筛选恐龙概念下实体 -> 食性为植食性的实体 -> 其中体重最大的

(11) 如何实现关系的推理,比如鱼石螈演进关系的演进关系是?

解:原始图谱关系:鱼石螈 -> 演进关系 ->蜥螈 -> 演进关系 -> 异齿龙

对齐结果:(实体-等于-鱼石螈)且(属性-等于-演进关系);(属性-等于-演进关系)

答案:鱼石螈的演进关系是蜥螈,而蜥螈的演进关系是异齿龙。

(12) 为什么说解析模块便于快速扩展?

解:实体、概念、属性查询接口均封装为独立方法。

(13) 对比类、判断类的问题回答如何更加口语化?

解:问答prompt调优

(14) 如何快速定位问题?

解:增加debug机制,即接口调用时,debug机制会将每个阶段的处理结果均记录下来,并返回。

(15) 目前支持多少轮问答?

解:理论上支持N多轮,且N支持配置

(16) 如何提高指代消解的准确率?

解:对齐prompt增加历史的参考实体或概念

7. 遗留的问题

(1) 基于属性值查实体未实现,分析部分badcase,属于此类情况

(2) 路径查询未实现,因为当前图谱关系数量极少

8. 总结

一句话足矣~

本文主要是KBQA方案基于LLM实现,主要模块包括对齐、解析、润色、多轮问答等内容,而且基于业务测试集效果相对较好。

纯纯的干货篇!!


原创声明,禁止转载!