GPU 不是问题,Torch 和 Onnxruntime 都支持
# For torch
curl -L https://download.pytorch.org/libtorch/cpu/libtorch-macos-arm64-2.5.1.zip > libtorch.zip
unzip -q libtorch.zip
bundle config build.torch-rb --with-torch-dir=/path/to/libtorch
gem install torch-rb
Torch.tensor(1.0).to("cuda")
# For onnxruntime
# Download gpu version https://github.com/microsoft/onnxruntime/releases
OnnxRuntime.ffi_lib = "path/to/lib/libonnxruntime.so"
model = OnnxRuntime::Model.new("/path/to/model.onnx", providers: ["CUDAExecutionProvider"])
然后代码再调试下即可,原代码设计成 DEVICE=cuda ruby demo.rb,不过没去调试。
其它地方用过还是蛮丝滑的,只要显存够。
对的,要根据场景自己确定怎么应用,比如 redis 的 redlock 选择不占着卡死进程而是超时释放,代码逻辑就要兜底处理这个 lock 被释放时的处理。
redis 作者对这篇文章有回复的,也写的有些道理,有兴趣可以自己找着看
业务无关的纯技术内部实现的复用部分 -> concerns 业务有关的复用代码 -> services
羡慕 UI 能做这么好看
用的什么技术栈?ActionCable?IM 框架?
已经分布式锁了就不需要叠加 synchronized 了吧。 不同分布式锁实现的超时处理机制不一样。 gem 的话,redis 的 redlock,pg 的 with_advisory_lock,都可以拿来就用。
之前用了 OpenResty,接收所有域名指向到默认 Rails 应用(没有做数据隔离),配置自动获取 Let's Encrypt 就可用。
每一个客户有需要自己域名 cname 过来即可。
问题是有大量莫名的乱七八糟的域名解析过来,导致大量无效的证书获取触发 Let's encrypt 的 limit 限制。
还在找更好的方案
提另外一个担心又欣慰的事,在大家喊引入静态类型的时候,matz 坚持不在 Ruby 中引入类型,坚持把 type 隔离在外部库来支持。
linux, vim, rvm, firefox, 就这么多,本机开发调试。
pg/redis/elastic_search/qdrant/Rabbit MQ/Kafka等各种配套服务可以考虑docker直接起服务; 一般超稳定的软件比如 pg 我会本机直接安装,各种不确定的用 docker。
都 NLUI 了,前后端分离是啥
勿执勿念,放弃放下。
我可以比年轻人拿得少一点(不止一点),
摆正心态,打工挣钱,难受都是自己为难自己。
那就是我没用好(悲伤)
这是直接用 sidekiq(include Sidekiq::Job)会发生的问题,
还是基于 ActiveJob 使用也会发生的问题?
第一次看到这么惊喜的年龄要求
把它设计成 resource,then restful
管理层也只是一个工作,没什么不一样。
遵守,挺好的。
ChatClient 就是一个 Faraday.new,太简单了所以没贴。细节在这里: https://github.com/as181920/openai_api_proxy/blob/main/lib/openai_api_proxy/chat_client.rb
前些天在老产品上面也添加了一个给老用户体验的, https://www.vcooline.com。
主要加了返回 stream 的处理(一个字一个字蹦出来)
def perform_openai_request(prompt:)
completion_content = ""
start_chunk_message
OpenaiApiProxy::ChatClient.new(api_key: ‘’, organization_id: ‘’).create(
model: "gpt-3.5-turbo",
messages: generate_chat_messages(prompt),
max_tokens:1234,
user: user.to_gid.to_s,
stream: true
) do |reqt|
reqt.options.on_data = Proc.new do |chunk, overall_received_bytes, env|
chunk_contents = handle_openai_chunk_data(chunk, overall_received_bytes, env)
chunk_contents.compact_blank.map { |chunk_content| completion_content.concat(chunk_content) }
end
end
completion_content.presence
&.tap { |content| decrease_usage_quota(content:) }
&.tap { |content| save_bot_message(content:) }
rescue OpenaiApiProxy::Client::ServerError, OpenaiApiProxy::Client::InternalError => e
Rails.logger.error "#{self.class.name} perform #{e.class.name}: #{e.message}"
send_chunk_message(content: "系统繁忙,请稍候再试。")
end
def handle_openai_chunk_data(chunk, _overall_received_bytes, _env)
chunk.force_encoding("UTF-8").encode("UTF-8", invalid: :replace, undef: :replace, replace: "")
.split("\n\n")
.map { |line| line.sub(/^data:\ */, "") }
.compact_blank
.map.each_with_object([]) do |chunk_line, chunk_contents|
break chunk_contents if chunk_line == "[DONE]"
chunk_info = JSON.parse chunk_line
# start_chunk_message if chunk_info.dig("choices", 0, "delta", "role").eql?("assistant")
chunk_info.dig("choices", 0, "delta", "content").presence
&.tap { |chunk_content| chunk_contents.push(chunk_content) }
&.tap { |chunk_content| send_chunk_message(content: chunk_content) }
end
end
def send_chunk_message(content:)
start_chunk_input
message.broadcast_append_to \
ActionView::RecordIdentifier.dom_id(message.conversation, :namespace_example),
target: reply_message_dom_id,
html: content
end
效率真厉害
http.get(api).body.dig "choices", 0, "text" 是不是大概就这么一行的事情
也不是一定要购买云服务,一些基础的软件 redis/pg/mq 等自建还是蛮稳定的,看业务要求到什么程度。
Ruby 工具书
Rails Guide(类似于本科学经济学原理,研究生学经济学原理,博士还是学经济学原理)
源码不着急
如果有 turbo 但没有 stimulus 的情况,可以考虑
document.addEventListener("turbo:load", function()
document.addEventListener("turbo:frame-load", function(ev)
来做初始化
这边一直是这么干的,所有部署全部是 production env。走 cap 的 linked_file 文件(并转化成 ENV 参数),来区分不同环境需要的不同配置。
class Application < Rails::Application
config.before_configuration do
env_file = Rails.root.join("config/local_env.yml")
YAML.load_file(env_file, aliases: true)[Rails.env].to_h.each do |key, value|
ENV[key.to_s] = value.to_s
end if File.file?(env_file)
end
end
这是汇付天下的产品吧,我去了解了解
最近遇到分账需求,调研了一下费用普遍过高,不适合中小商家使用,目前考虑单独对接微信&支付宝。
在这两大平台提供原生分账能力的情况下,不清楚现在聚合支付机构收取那么高的年费是基于什么缘故(涉及分账就贵,牌照虽然贵,另外没牌照走银行托管账户方案的也贵)。
/ fix disable_with on link and submit inside turbo-frame
Rails.delegate(document, Rails.linkDisableSelector, "turbo:before-cache", Rails.enableElement)
Rails.delegate(document, Rails.buttonDisableSelector, "turbo:before-cache", Rails.enableElement)
Rails.delegate(document, Rails.buttonDisableSelector, "turbo:submit-end", Rails.enableElement)
Rails.delegate(document, Rails.formSubmitSelector, "turbo:submit-start", Rails.disableElement)
Rails.delegate(document, Rails.formSubmitSelector, "turbo:submit-end", Rails.enableElement)
Rails.delegate(document, Rails.formSubmitSelector, "turbo:before-cache", Rails.enableElement)