基于LLM的自行车道CAD

LLM(大型语言模型)是强大的工具。对于许多人来说,用语言表达愿望通常比浏览复杂的 GUI 更简单。

1、系统简介和环境搭建

 urb-x.ch,这是一家专门从事自行车道建设的公司。轨道采用模块化构建块进行独特设计,可以通过多种方式进行组合。当拼凑在一起时,整个轨道网络形成了这些构建块的树形结构。

在某些方面,这个任务可以看作是一个视频游戏沙盒。可以将其视为在《过山车大亨》或《赛道狂热》中建造轨道。然而,虽然这些游戏提供了直观的设计体验,但它们无法提供土木工程项目所需的精度水平。另一方面,传统的 CAD 程序不允许大规模使用这样的模块化系统。

建立了一个无/低代码系统,让你可以轻松地创建车道,该系统构建在 Rhino 和 Grasshopper 的基础上。收获是什么?你必须投入一些时间来熟悉可用的组件。

与大多数视频游戏一样,与系统的交互可以被视为数据库系统中的事务。为此,设计了一个简单的 json/ pydantic 模式来存储轨道的配置。现在更新变成了简单的配置更新。我们将此配置称为“TrackConfig”。

{"version": "0.0.2","library_dir": ["/Users/lucas/projects/gh/"],"origin": {"position": [0.0,0.0,0.0],"rotation": [0.0,0.0,0.0]},"global_upgrades": {"PV": true,"HEATING": true,"FE3": {"LR": false}},"instance": {"id": "Oliver","part_name": "XC50-4L","children": {"-1": {"id": "Liam","part_name": "XC50-4R","children": {"-1": {"id": "Oliver","part_name": "XC50-4R","children": {"-1": {"id": "Ethan","part_name": "XC50-4R","children": {}}}}}}}},"configs": {},"selected": "Oliver"
}

作为一个项目,现在使用新的 OpenAI 函数来解析模型输出/实际上限制模型输出以匹配预期格式。

最初,目标是直接生成新的 TrackConfig。这种方法效果很好,但有一个显着的缺点:延迟非常大。不过,这还不错:大约 15 秒,这在大多数情况下仍然比使用 GUI 更快。总而言之,发现这对于迭代过程来说是不可接受的,并且希望加快速度。使用 W&B Prompts 记录所有内容,显示延迟和许多其他指标。它们工作得非常好,特别是在深入研究模型结果时!

为了应对延迟挑战,策略是减少模型所需的输出。这种方法的结果是集成了简单的更新功能。

from typing import Any, Optional, Unionfrom PythonModules.schema import TrackConfig, Part, PartNamesfrom pydantic import BaseModel, Fieldclass UpdatePart(BaseModel):"""Updating or creating a part with the given id and part_name"""reasoning: str = Field(..., description="Answer all reasoning questions")id: str = Field(..., description="The unique id of a part. This is a unique random english first name.")part_name: PartNames = Field(..., description="The name of the part e.g. 'XS12'")parent: str = Field("", description="The id of the parent part or '' if the part is the root part. Usually This is the current selected part.")index: int = Field(-1, description="Where to insert the new part. -1 means append.")def __call__(self, track_config: Optional[TrackConfig] = None):return #code ommitedclass UpdateSelection(BaseModel):"""Select the part with the given id"""reasoning: str = Field(..., description="Which id's parts could be selected? Why does each part make sense or not?")id: str = Field(..., description="The unique id of a part. This is a unique random english first name.")def __call__(self, track_config: Optional[TrackConfig] = None):print(f"UpdateSelection(reasoning={self.reasoning}, id={id})")return #code ommited# Other possible updates

虽然LLM很强大,但它们有一个一致的缺点:零样本预测可能不可靠。带有推理的输出要可靠得多。不幸的是,目前还没有任何 LangChain 链能够提供推理与 OpenAI 函数调用的组合。

公认的黑客解决方案是在函数调用中强制使用“推理”字段。前面讨论的 pydantic 模式说明了一个典型的例子。

这种策略虽然非常规,但已被证明是无价的,并且可能成为类似应用程序的关键要点。

现在,讨论延迟。如果没有推理组件,延迟会徘徊在 1.5 秒左右,这个值低得惊人。添加推理后,延迟会根据所采用的推理的深度和数量而变化。本质上,增加的运行时间与推理标记的数量成线性比例。那里相当简单。大多数情况下,延迟时间都小于 4 秒,尽管优化仍在进行中并且希望能将其降低。

借助 W&B Prompts,可以制作提示并观察其他用户如何与工具交互。这种洞察力能够分析两种提示的功效,从而进行改进,例如改进系统提示以增强预测。

让我们深入探讨提示业务。由于 GPT-3 Turbo 的上下文大小相当大,而预测令牌数量相当少,有一些空间可以使用,所以可以在提示上挥霍。

把所有认为重要的东西都扔掉了,保持干净整洁。查看下面进行的设置:

system_template = """
You are a world class assistant, helping an engineer to build an amazing street network from prefefined parts. The whole system is modular. 
You are responsible for deciding on which updates to do to the underlying configuration. The engineer will then update the configuration based on your input. 
You get access to a pointer named 'selected'. This id shows you relative to what you probably should append things to.
The whole track configuration is stored in a json file. In the instance key a tree of parts exists. The decendant of a child is the "children" field. The main child has key "-1".
The whole track consisting of a tree should make it easier to describe on where to append things.The configuration is based on the following pydantic schema:class PartNames(str, Enum):Straigt30mElement = "XS12"CurveRight50mRadius10mLenthgElement = "XC50-4L"CurveLeft50mRadius10mLenthgElement = "XC50-4R"DeletedElement = "Deleted"class Origin(BaseModel):position: List[float] = Field(..., description="The origin position coordinates (x,y,z))")rotation: List[float] = Field(..., description="The origin rotation angles in degrees (x,y,z)")class Part(BaseModel):id: str = Field(..., description="The unique id of a part. This is a unique random english first name.")part_name: PartNames = Field(..., description="The name of the part")children: Optional[Dict[str, 'Part']] = Field({}, description="Dictionary of child parts. Key=='next' is the default next part")Part.update_forward_refs()  # This updates Element to include the recursive reference to itselfclass TrackConfig(BaseModel):version: str = Field(..., description="The version of the track configuration")library_dir: List[str] = Field(..., description="List of paths to the libraries")origin: Origin = Field(..., description="The origin position and rotation of the track")global_upgrades: Dict[str, Any] = Field(..., description="Global upgrades for every element")instance: Part = Field(..., description="Part instances of the track")configs: Dict[str, Dict[str, Any]] = Field(..., description="Configuration dictionary for the track configuration")selected: str = Field(..., description="The id of the selected Element")For new elements think of a new english first name as id! Think of a random name.
If not specified otherwise append or add new parts to the selected part. Never add new parts to a parent as a different child then -1, unless specified otherwise!
If a parent has other children it usually is asumed that the child with key -1 is the main child and that you should append to that one or one of its children.Altough also visible in the schema, the following part_name's are available:
Straigt 30m Element: "XS12"
Curve Right!! 50m Radius 10m outer Length Element: "XC50-4L"
Curve Left!!  50m Radius 10m outer Length Element: "XC50-4R"Reasons for the update fields should answer the following questions! You have to answer all of them:
- Which id do you want to update or is it a new id?
- What part_name do you want to use?
- Why this part_name?
- What parents could you use?
- If the parent already has children, why do you want to replace main child?"""prompt_template = """
The current configuration is as follows:
--------------------
{track_config}
--------------------
Use the given format to pick update steps from the following input:
--------------------
{input}
--------------------
Tips: Answer all questions.
Tips: Make sure to answer in the correct format!!!
"""

现在让我们看看模型调用:

class Track:def __init__(self, llm, system_template, prompt_template):self.path = "track.json"self.new_config = Noneprompt_msgs = [SystemMessage(content= system_template),HumanMessagePromptTemplate.from_template(prompt_template)]prompt = ChatPromptTemplate(messages=prompt_msgs)self.chain = create_openai_fn_chain([UpdatePart,UpdateSelection], llm, prompt, verbose=False)@propertydef track_config(self):if not self.new_config:data_dict = json.load(open(self.path, "r"))track_config = TrackConfig(**data_dict)self.new_config = track_configreturn self.new_config@track_config.setterdef track_config(self, track_config: TrackConfig):self.new_config = track_configdef store(self):json.dump(self.track_config.dict(), open(self.path, "w"), indent=2)def agent(self):# interactively update the track_config# asks for user input and calls the callback functionwhile prompt:=input("How should the track be updated? to quit press enter without input."):self(prompt)# Possibly wrap the call in retries if the to predict format is very difficult# @retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6))def __call__(self, input) -> Any:json_str = json.dumps(self.track_config.dict(), indent=2)function:Union[UpdatePart,UpdateSelection] = self.chain.run(input = input, track_config=json_str)# call function with the track_configres = function(self.track_config)# store the new track_configself.store()return resmodel = "gpt-3.5-turbo"
llm = ChatOpenAI(model=model,temperature=0.9)
track = Track(llm, system_template, prompt_template)

现在我们要么使用 track.agent() 方法来连续更新配置。或者使用单个命令:

track("append a new right element to the track")
track("Add a straight part to the last added track")
...

2、如何使用 W&B 提示

此处使用 W&B Prompts 主要是为了记录并查看其他人如何使用我的工具。这是一次了解人们在建造轨道时所做出的不同假设的旅程,并了解模型提出的古怪假设。您可以在函数调用的“原因”字段中发现这些模型假设。

只需设置一个环境变量,然后就可以开始了。

# we need a single line of code to start tracing LangChain with W&B
os.environ["LANGCHAIN_WANDB_TRACING"] = "true"

现在,锁链只是一场单步舞。如果能把它分成几个阶段,特别是分离出推理,那就很巧妙了。但是,这是一项正在进行的工作。

以下是 CAD 中车道的形状:

注意:我们只是在这里展示车道。为了清晰起见,所有额外的东西,如房屋、街道和桥梁,都没有显示在图中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/10982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HCIP的学习(15)

第六章,BGP—边界网关协议 自治系统—AS ​ 定义:由一个单一的机构或组织所管理的一系列IP网络及其设备所构成的集合。 ​ AS的来源: 整个网络规模过大,会导致路由信息收敛速度过慢,设备对相同目标认知不同。AS之间…

全国院校及梯度排序深度解析课(免费下载-帮助更多高考生做出人生重要的选择。)

"全国院校及梯度排序深度解析课"旨在深入探讨全国院校的排名及梯度排序原理。通过系统解析各院校的学术声誉、师资力量、科研水平等因素,帮助学员全面了解院校排名的背后逻辑,为选择合适院校提供理论支持。 课程大小:7G 课程下载…

Java面试之分布式篇

分布式锁的实现方案 (1)用数据库实现分布式锁比较简单,就是创建一张锁表,数据库对字段作唯一性约束。加锁的时候,在锁表中增加一条记录即可;释放锁的时候删除锁记录就行。如果有并发请求同时提交到数据库&…

css-页面布局-定位大解析-每文一言(世界上,没有人可以支持你一辈子)

🎐每文一言 世界上,没有人可以支持你一辈子 目录 🎐每文一言 🎁css定位 🧧静态定位 position: static 🎄相对定位 position:relative 🎀绝对定位 position:absolute 🎃固定定位 position…

Yoast SEO Premium插件下载,提升您的网站SEO排名

在当今数字化时代,网站的搜索引擎优化(SEO)至关重要。它不仅影响着网站的可见度,更直接关系到您的在线业务成功与否。如果您正在寻找一个能够显著提升网站SEO表现的工具,Yoast SEO Premium插件将是您的理想选择。 为什…

(docker)进入容器后如何使用本机gpu

首次创建容器,不能直接使用本机gpu 在系统终端进行如下配置: 1.安装NVIDIA Container Toolkit 进入Nvidia官网Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit 1.15.0 documentation,安装NVIDIA Container Toolkit …

AI预测福彩3D采取887定位策略+杀断组+杀和尾+杀和值012缩水测试5月12日预测第1弹

前段时间工作太忙,手头上各种事情较多,没有静下心来对我的AI模型预测结果进行进一步分析筛选,导致最近连续几期与实际开奖结果相差较大。当然,客观来说,搞6码定位的确难度比较大,昨天跟几个常年研究3D的彩友…

【RAG 论文】FiD:一种将 retrieved docs 合并输入给 LM 的方法

论文: Leveraging Passage Retrieval with Generative Models for Open Domain Question Answering ⭐⭐⭐⭐ EACL 2021, Facebook AI Research 论文速读 在 RAG 中,如何将检索出的 passages 做聚合并输入到生成模型是一个问题,本文提出了一…

java基础知识点总结2024版(8万字超详细整理)

java基础知识点总结2024版(超详细整理) 这里写目录标题 java基础知识点总结2024版(超详细整理)java语言的特点1.简单性2.面向对象3.分布式4.健壮性5.安全性6.体系结构中立7.可移植性8.解释性9.多线程10.动态性 初识java中的main方…

Java类与对象(一)

类的定义与使用 在Java中使用关键字class定义一个类,格式如下: class 类名{// 成员变量/字段/属性//成员方法/行为 }Java中类和c语言中的结构体有点类似, 在Java中类名一般采用大驼峰(每个首字母大写)的形式&#xf…

类和对象一(从封装开始讲述)

目录: 一.封装 二.封装扩展之包,自定义包 三.访问限定符 四.static成员 一.封装:封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互。面向对象…

Reactor Netty TCP 服务器端-响应式编程-011

🤗 ApiHug {Postman|Swagger|Api...} = 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱,有温度,有质量,有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace The Next Generation API Development Platform…

一款简约大气的个人单页介绍主页(附加源码)

一款简约大气的个人单页介绍主页(附加源码) 效果图部分源码领取源码下期更新预报 效果图 部分源码 .box_bg{width: 100%;height: 100%; }.wenzi{text-align: center;float: left;display: inline;width: 112px;line-height: 48px; } .wenzi2{text-align…

Hikyuu高性能量化研究框架助力探索

Hikyuu Quant Framework 是一款基于C/Python的开源量化交易分析与研究工具,主要用于A股市场的交易策略分析与回测,目前不支持期货等,需要自行改造。 Hikyuu的目标 Hikyuu的最初目的是为了快速对A股全市场股票进行策略回测和验证&#xff0c…

【C++11】列表初始化、右值引用的详细讲解(上)

前言 在一开始学C之前我们就简单的了解了一下C的发展历史。 相比较而言,C11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率加了许多特性,约140个新特性。使得C…

《A data independent approach to generate adversarial patches》论文分享(侵删)

原文链接:A data independent approach to generate adversarial patches | Machine Vision and Applications author{Xingyu Zhou and Zhisong Pan and Yexin Duan and Jin Zhang and Shuaihui Wang}, 一、介绍 在图像识别领域,与数字域中的攻击相比…

【C++杂货铺铺】AVL树

目录 🌈前言🌈 📁 概念 📁 节点的定义 📁 插入 📁 旋转 1 . 新节点插入较高左子树的左侧---左左:右单旋 2. 新节点插入较高右子树的右侧---右右:左单旋 3. 新节点插入较高左…

工业级路由器的穿透力是不是更强(原创科普)

今天我想和大家聊聊工业级路由器的一个重要特性——穿透力。作为一名从事工业网络通信的工程师,我发现很多用户在选择工业级路由器时,都会问到一个问题:"工业级路由器的穿透力是不是更强?"下面就让我来为大家解答这个疑问。当然如果有通信产品需要也可以关注星创易联…

Kafka效率篇-提升效率三板斧

kafka在效率上做了很多的努力。最初的一个使用场景是处理网页上活跃的数据,它往往有非常大的体量,每个页面都能产生数十条写入。而且我们假设每条消息都会被至少一个消费者消费(通常是多个),因此,我们努力让…

二维费用背包分组背包

二维费用背包&分组背包 一定要做的