2024 Clojure状态调查中分享您的想法!

欢迎!请参阅关于页面以获取更多关于如何使用本网站的信息。

+2 投票
Clojure CLI

我写过一些依赖二进制资源(例如原生共享库)以及其他有大资源(例如llm权重)的库。

原则上,这两种类型的依赖都可以通过deps工具满足而无需任何更改,因为deps cli可以获取资源并将其添加到类路径。

但是,还有一些额外的挑战,使得在使用deps cli处理大型和/或二进制资源时感到有些不便。

大型资源很大

我避免使用deps工具处理大型资源,因为有几个缺失的功能

a) 下载依赖项之前没有是/否提示。

当调用cli时,下载可能100多兆的依赖项似乎是合理的,但直接下载千兆级别数据依赖项而事先没有询问则感觉不太合适。

b) 下载依赖项时没有进度指示器

下载依赖项通常很快,但在下载几GB依赖项时有一个进度指示器会更好。

原生依赖项通常很大

原生依赖项的大小可能从几MB到1GB不等(例如Chromium嵌入式框架)。

原生依赖项依赖于平台/操作系统

我认为有一些maven魔法可以帮助解决这个问题,但我还没有机会看看。不管怎样,运行程序所需的工件依赖于程序运行的平台。通常,包括所有可能的平台的工件是可行的,但这可能是不必要地使用资源,并且可能在某些情况下不起作用。

在加载之前必须从jar中提取共享库

许多ffi库(如JNA)会为你做这件事。它根据ffi库以非正式的方式进行实现。它可能或可能不起作用,具体取决于共享库是独立库还是依赖于其他共享库。

可能的,deps工具可以使用一种可接受、统一的方法提取共享库。

预先编译的Linux共享库几乎不起作用

你可以预先为mac osx和windows编译共享库,以获得广泛的兼容性且“即用即行”。在Linux上,有很多需要注意的地方。一般来说,如果你有一个独立的共享库并且用它进行了编译(例如,使用zig [llmdb]),则可以得到基本可以工作的东西,但如果有一个依赖多个不使用zig的共享库(例如,graphviz),则兼容性将大幅度下降。

原生依赖项应该从源代码编译?

一些包管理器提供预编译的二进制文件(例如conda),但似乎许多包管理器倾向于从源代码编译(例如,pip、macports、homebrew等)。

从源代码编译可能有助于以下问题:

  • 从源代码编译避开了在Linux上提供本地依赖项的许多挑战
  • 本地依赖项可能是Git依赖项!
  • 有些开发者非常不喜欢预编译的二进制文件,并强烈倾向于从源代码编译。

明显,支持从源代码编译有其自身的挑战。


上述内容涵盖了关于大型和/或二进制资源的问题。以下是几个具体案例:

  • clj-cef:包装了 chromium 内嵌框架。框架本身大约为 0.5-1.5GB,取决于平台,包括共享库和大型资源文件。还需要额外的小型共享库。
  • clj-graphviz:包装了 graphviz 的C库。比较棘手,因为存在多个共享库,每个共享库都有额外的依赖(例如,libpng)。
  • llama.clj:包装了 llama.cpp 库,用于本地运行 llm。还希望添加特定的 llm 重量作为依赖项,但它们的体积可以非常大(例如,几个吉字节到数百吉字节)。此外,llama.cpp 可以编译为支持gpu,但我还没有想出一种在没有从源代码编译选项的情况下便携的方式。

我知道这和现有工具有很多重叠,所以也许可以以某种方式让依赖项 cli 集成到现有工具中

  • 获取原生依赖项:pip,conda,homebrew,macports,apt,scoop 等。
  • 获取数据依赖项:hugging face,https://dvc.org/

无论如何,我已经多次尝试找到包含本地和/或大型依赖项的良好方法,所有这些选项仍然感觉相当不自然。

登录注册以回答此问题。

...