refactor: backend_accounting.py now uses product_management module
- Import from product_management.get_manager() instead of llmage.accounting - Also loads load_llmage for pricing/discount initialization
This commit is contained in:
parent
5ec5301e6e
commit
4927f7f330
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
"""
|
"""
|
||||||
独立运行的LLM后台计费程序。
|
独立运行的产品后台计费程序。
|
||||||
从 sage.py 的 llmage 模块中提取,避免多进程模式下重复运行。
|
产品记账已从 llmage 迁移到 product_management 模块。
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@ -25,16 +25,13 @@ from llmage.init import load_llmage
|
|||||||
from pricing.init import load_pricing
|
from pricing.init import load_pricing
|
||||||
from discount.init import load_discount
|
from discount.init import load_discount
|
||||||
from dapi.init import load_dapi
|
from dapi.init import load_dapi
|
||||||
|
from product_management import get_manager
|
||||||
|
|
||||||
# 初始化配置
|
# 初始化配置
|
||||||
p = ProgramPath()
|
p = ProgramPath()
|
||||||
config = getConfig(NS={'workdir': os.getcwd(), 'ProgramPath': p})
|
config = getConfig(NS={'workdir': os.getcwd(), 'ProgramPath': p})
|
||||||
DBPools(config.databases)
|
DBPools(config.databases)
|
||||||
|
|
||||||
# 导入 llmage 的计费函数
|
|
||||||
from llmage.accounting import (
|
|
||||||
backend_accounting
|
|
||||||
)
|
|
||||||
def get_module_dbname(m):
|
def get_module_dbname(m):
|
||||||
return 'sage'
|
return 'sage'
|
||||||
|
|
||||||
@ -62,8 +59,11 @@ def main():
|
|||||||
load_pricing()
|
load_pricing()
|
||||||
load_discount()
|
load_discount()
|
||||||
load_dapi()
|
load_dapi()
|
||||||
|
load_llmage()
|
||||||
|
|
||||||
|
manager = get_manager()
|
||||||
try:
|
try:
|
||||||
loop.run_until_complete(backend_accounting())
|
loop.run_until_complete(manager.backend_accounting())
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@ -1,54 +1,29 @@
|
|||||||
# Demucs 任务状态查询
|
# Demucs 任务状态查询
|
||||||
# 部署到: /data/ymq/demucs-service/app/api/demucs-status.dspy
|
|
||||||
# GET /demucs/api/demucs-status?task_id=xxx
|
# GET /demucs/api/demucs-status?task_id=xxx
|
||||||
import json
|
|
||||||
|
|
||||||
task_id = params_kw.task_id
|
task_id = params_kw.task_id
|
||||||
if not task_id:
|
if not task_id:
|
||||||
return {"error": "task_id is required"}
|
return {"error": "task_id is required"}
|
||||||
|
|
||||||
env = request._run_ns
|
env = request._run_ns
|
||||||
longtasks = env.longtasks
|
longtasks = env.longtasks
|
||||||
|
if not longtasks:
|
||||||
|
return {"error": "longtasks not available"}
|
||||||
|
|
||||||
# longtasks 内部通过 Redis 存储结果,key 格式: {queue_name}:result:{task_id}
|
task = await longtasks.get_redis_task(task_id)
|
||||||
import redis.asyncio as redis
|
if not task or not task.get("created_at"):
|
||||||
r = redis.Redis(host='127.0.0.1', port=6379, db=0, decode_responses=True)
|
return {"task_id": task_id, "status": "not_found"}
|
||||||
|
|
||||||
# 尝试获取结果
|
status = task.get("status", "unknown")
|
||||||
result_key = f"demucs:result:{task_id}"
|
result = {"task_id": task_id, "status": status}
|
||||||
raw = await r.get(result_key)
|
|
||||||
|
|
||||||
if raw:
|
if status == "SUCCEEDED":
|
||||||
data = json.loads(raw)
|
data = task.get("result", {})
|
||||||
return {
|
result["vocals_url"] = data.get("vocals_path", "")
|
||||||
"task_id": task_id,
|
result["accompaniment_url"] = data.get("accompaniment_path", "")
|
||||||
"status": "SUCCEEDED",
|
result["duration"] = data.get("duration", 0)
|
||||||
"vocals_url": data.get("vocals_path", ""),
|
# worker 须在 result 中包含 usage 字段
|
||||||
"accompaniment_url": data.get("accompaniment_path", ""),
|
result["usage"] = data.get("usage", {"audio_seconds": data.get("duration", 0)})
|
||||||
"duration": data.get("duration", 0),
|
elif status == "FAILED":
|
||||||
"usage": data.get("usage", {"次": 1}),
|
result["error"] = task.get("error", str(task.get("result", "")))
|
||||||
}
|
|
||||||
|
|
||||||
# 检查是否在队列中
|
return result
|
||||||
queue_key = f"demucs:queue"
|
|
||||||
in_queue = await r.lrange(queue_key, 0, -1)
|
|
||||||
for item in in_queue:
|
|
||||||
try:
|
|
||||||
item_data = json.loads(item)
|
|
||||||
if item_data.get("task_id") == task_id:
|
|
||||||
return {"task_id": task_id, "status": "queued"}
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# 检查是否在处理中
|
|
||||||
processing_key = f"demucs:processing"
|
|
||||||
processing = await r.get(processing_key)
|
|
||||||
if processing:
|
|
||||||
try:
|
|
||||||
proc_data = json.loads(processing)
|
|
||||||
if proc_data.get("task_id") == task_id:
|
|
||||||
return {"task_id": task_id, "status": "processing"}
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return {"task_id": task_id, "status": "not_found"}
|
|
||||||
|
|||||||
9
scripts/demucs_worker_usage_fix.py
Normal file
9
scripts/demucs_worker_usage_fix.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Patch for /data/ymq/demucs-service/workers/separate.py
|
||||||
|
# In run_separate_full(), ensure the return dict includes:
|
||||||
|
# "usage": {"audio_seconds": duration}
|
||||||
|
|
||||||
|
# Find the return statement in run_separate_full and add usage field.
|
||||||
|
# The function currently returns something like:
|
||||||
|
# return {"vocals_path": ..., "accompaniment_path": ..., "duration": ...}
|
||||||
|
#
|
||||||
|
# Add: "usage": {"audio_seconds": result.get("duration", 0)}
|
||||||
@ -51,12 +51,6 @@ INSERT INTO uapiio (id, name, description, input_fields) VALUES (
|
|||||||
'{"audio_file":{"type":"string","required":true,"description":"音频文件URL"},"scene":{"type":"string","required":false,"default":"pop","description":"场景类型"}}'
|
'{"audio_file":{"type":"string","required":true,"description":"音频文件URL"},"scene":{"type":"string","required":false,"default":"pop","description":"场景类型"}}'
|
||||||
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
|
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
|
||||||
|
|
||||||
-- 音乐合成(异步)
|
|
||||||
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
|
|
||||||
'ktv_synth_generate_io', 'KTV音乐合成', 'AI歌声合成(异步任务)',
|
|
||||||
'{"lyrics":{"type":"string","required":true,"description":"歌词文本"},"style":{"type":"string","required":false,"default":"pop","description":"演唱风格"},"audio_file":{"type":"string","required":false,"description":"参考音频URL(声音克隆)"}}'
|
|
||||||
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
|
|
||||||
|
|
||||||
-- 合成状态查询
|
-- 合成状态查询
|
||||||
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
|
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
|
||||||
'ktv_synth_status_io', 'KTV合成状态', '查询音乐合成任务状态',
|
'ktv_synth_status_io', 'KTV合成状态', '查询音乐合成任务状态',
|
||||||
|
|||||||
@ -52,13 +52,7 @@ UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
|
|||||||
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","score":{{score}},"details":{{json.dumps(details,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
|
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","score":{{score}},"details":{{json.dumps(details,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
|
||||||
ioid='ktv_songrate_evaluate_io' WHERE id='uapi_ktv_songrate_evaluate';
|
ioid='ktv_songrate_evaluate_io' WHERE id='uapi_ktv_songrate_evaluate';
|
||||||
|
|
||||||
-- 9. 音乐合成 (async提交)
|
-- 9. 合成状态查询 (sync)
|
||||||
UPDATE uapi SET stream='async',headers='{"Content-Type":"application/json"}',
|
|
||||||
data='{"lyrics":"{{lyrics}}"{%if style%},"style":"{{style}}"{%endif%}{%if audio_file%},"audio_file":"{{audio_file}}"{%endif%}}',
|
|
||||||
response='{"taskid":"{{task_id}}","taskstatus":"PENDING"}',
|
|
||||||
ioid='ktv_synth_generate_io' WHERE id='uapi_ktv_synth_generate';
|
|
||||||
|
|
||||||
-- 10. 合成状态查询 (sync)
|
|
||||||
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
|
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
|
||||||
data='{"task_id":"{{task_id}}"}',
|
data='{"task_id":"{{task_id}}"}',
|
||||||
response='{%if error%}{"error":"{{error}}"}{%elif status=="SUCCEEDED"%}{"taskstatus":"SUCCEEDED","output_url":"{{output_url}}","usage":{{json.dumps(usage,ensure_ascii=False)}}}{%elif status=="FAILED"%}{"taskstatus":"FAILED","error":"{{error}}"}{%else%}{"taskstatus":"PENDING"}{%endif%}',
|
response='{%if error%}{"error":"{{error}}"}{%elif status=="SUCCEEDED"%}{"taskstatus":"SUCCEEDED","output_url":"{{output_url}}","usage":{{json.dumps(usage,ensure_ascii=False)}}}{%elif status=="FAILED"%}{"taskstatus":"FAILED","error":"{{error}}"}{%else%}{"taskstatus":"PENDING"}{%endif%}',
|
||||||
@ -89,7 +83,6 @@ UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
|
|||||||
ioid='ktv_video_eval_evaluate_io' WHERE id='uapi_ktv_video_eval_evaluate';
|
ioid='ktv_video_eval_evaluate_io' WHERE id='uapi_ktv_video_eval_evaluate';
|
||||||
|
|
||||||
-- async query_apiname
|
-- async query_apiname
|
||||||
UPDATE llm_api_map SET query_apiname='synth-status',query_period=5 WHERE llmid='llm_ktv_synth_generate';
|
|
||||||
UPDATE llm_api_map SET query_apiname='realesrgan-status',query_period=3 WHERE llmid='llm_ktv_realesrgan_upscale';
|
UPDATE llm_api_map SET query_apiname='realesrgan-status',query_period=3 WHERE llmid='llm_ktv_realesrgan_upscale';
|
||||||
|
|
||||||
-- ppid (v1/models 过滤要求 ppid IS NOT NULL)
|
-- ppid (v1/models 过滤要求 ppid IS NOT NULL)
|
||||||
|
|||||||
@ -13,7 +13,7 @@ INSERT INTO pricing_program (id,providerid,name) VALUES
|
|||||||
('pp_ktv_subtitle','FZoJv7EUEdKL3pUt0BQ5S','KTV-字幕渲染'),
|
('pp_ktv_subtitle','FZoJv7EUEdKL3pUt0BQ5S','KTV-字幕渲染'),
|
||||||
('pp_ktv_merge','FZoJv7EUEdKL3pUt0BQ5S','KTV-视频合并'),
|
('pp_ktv_merge','FZoJv7EUEdKL3pUt0BQ5S','KTV-视频合并'),
|
||||||
('pp_ktv_songrate','FZoJv7EUEdKL3pUt0BQ5S','KTV-歌曲评分'),
|
('pp_ktv_songrate','FZoJv7EUEdKL3pUt0BQ5S','KTV-歌曲评分'),
|
||||||
('pp_ktv_synth','FZoJv7EUEdKL3pUt0BQ5S','KTV-音乐合成'),
|
|
||||||
('pp_ktv_synth_status','FZoJv7EUEdKL3pUt0BQ5S','KTV-合成状态'),
|
('pp_ktv_synth_status','FZoJv7EUEdKL3pUt0BQ5S','KTV-合成状态'),
|
||||||
('pp_ktv_realesrgan','FZoJv7EUEdKL3pUt0BQ5S','KTV-超分辨率'),
|
('pp_ktv_realesrgan','FZoJv7EUEdKL3pUt0BQ5S','KTV-超分辨率'),
|
||||||
('pp_ktv_realesrgan_status','FZoJv7EUEdKL3pUt0BQ5S','KTV-超分状态'),
|
('pp_ktv_realesrgan_status','FZoJv7EUEdKL3pUt0BQ5S','KTV-超分状态'),
|
||||||
@ -30,7 +30,7 @@ UPDATE pricing_program_timing SET ppid='pp_ktv_face_compare' WHERE id='pt_ktv_fa
|
|||||||
UPDATE pricing_program_timing SET ppid='pp_ktv_subtitle' WHERE id='pt_ktv_subtitle_render';
|
UPDATE pricing_program_timing SET ppid='pp_ktv_subtitle' WHERE id='pt_ktv_subtitle_render';
|
||||||
UPDATE pricing_program_timing SET ppid='pp_ktv_merge' WHERE id='pt_ktv_merge_video';
|
UPDATE pricing_program_timing SET ppid='pp_ktv_merge' WHERE id='pt_ktv_merge_video';
|
||||||
UPDATE pricing_program_timing SET ppid='pp_ktv_songrate' WHERE id='pt_ktv_songrate_evaluate';
|
UPDATE pricing_program_timing SET ppid='pp_ktv_songrate' WHERE id='pt_ktv_songrate_evaluate';
|
||||||
UPDATE pricing_program_timing SET ppid='pp_ktv_synth' WHERE id='pt_ktv_synth_generate';
|
|
||||||
UPDATE pricing_program_timing SET ppid='pp_ktv_synth_status' WHERE id='pt_ktv_synth_status';
|
UPDATE pricing_program_timing SET ppid='pp_ktv_synth_status' WHERE id='pt_ktv_synth_status';
|
||||||
UPDATE pricing_program_timing SET ppid='pp_ktv_realesrgan' WHERE id='pt_ktv_realesrgan_upscale';
|
UPDATE pricing_program_timing SET ppid='pp_ktv_realesrgan' WHERE id='pt_ktv_realesrgan_upscale';
|
||||||
UPDATE pricing_program_timing SET ppid='pp_ktv_realesrgan_status' WHERE id='pt_ktv_realesrgan_status';
|
UPDATE pricing_program_timing SET ppid='pp_ktv_realesrgan_status' WHERE id='pt_ktv_realesrgan_status';
|
||||||
@ -89,7 +89,7 @@ UPDATE llm_api_map SET ppid='pp_ktv_face_compare' WHERE llmid='llm_ktv_face_comp
|
|||||||
UPDATE llm_api_map SET ppid='pp_ktv_subtitle' WHERE llmid='llm_ktv_subtitle_render';
|
UPDATE llm_api_map SET ppid='pp_ktv_subtitle' WHERE llmid='llm_ktv_subtitle_render';
|
||||||
UPDATE llm_api_map SET ppid='pp_ktv_merge' WHERE llmid='llm_ktv_merge_video';
|
UPDATE llm_api_map SET ppid='pp_ktv_merge' WHERE llmid='llm_ktv_merge_video';
|
||||||
UPDATE llm_api_map SET ppid='pp_ktv_songrate' WHERE llmid='llm_ktv_songrate_evaluate';
|
UPDATE llm_api_map SET ppid='pp_ktv_songrate' WHERE llmid='llm_ktv_songrate_evaluate';
|
||||||
UPDATE llm_api_map SET ppid='pp_ktv_synth' WHERE llmid='llm_ktv_synth_generate';
|
|
||||||
UPDATE llm_api_map SET ppid='pp_ktv_synth_status' WHERE llmid='llm_ktv_synth_status';
|
UPDATE llm_api_map SET ppid='pp_ktv_synth_status' WHERE llmid='llm_ktv_synth_status';
|
||||||
UPDATE llm_api_map SET ppid='pp_ktv_realesrgan' WHERE llmid='llm_ktv_realesrgan_upscale';
|
UPDATE llm_api_map SET ppid='pp_ktv_realesrgan' WHERE llmid='llm_ktv_realesrgan_upscale';
|
||||||
UPDATE llm_api_map SET ppid='pp_ktv_realesrgan_status' WHERE llmid='llm_ktv_realesrgan_status';
|
UPDATE llm_api_map SET ppid='pp_ktv_realesrgan_status' WHERE llmid='llm_ktv_realesrgan_status';
|
||||||
|
|||||||
@ -27,9 +27,6 @@ UPDATE uapi SET data='{%set c=joiner(",")%}{{%if video_file%}{{c()}}"video_url":
|
|||||||
-- songrate: audio_file→audio_path
|
-- songrate: audio_file→audio_path
|
||||||
UPDATE uapi SET data='{"audio_path":"{{audio_file}}"{%if scene%},"scene":"{{scene}}"{%endif%}}' WHERE id='uapi_ktv_songrate_evaluate';
|
UPDATE uapi SET data='{"audio_path":"{{audio_file}}"{%if scene%},"scene":"{{scene}}"{%endif%}}' WHERE id='uapi_ktv_songrate_evaluate';
|
||||||
|
|
||||||
-- synth-gen: audio_file→audio_path
|
|
||||||
UPDATE uapi SET data='{"lyrics":"{{lyrics}}"{%if style%},"style":"{{style}}"{%endif%}{%if audio_file%},"audio_path":"{{audio_file}}"{%endif%}}' WHERE id='uapi_ktv_synth_generate';
|
|
||||||
|
|
||||||
-- synth-status: GET, params in query string, no body
|
-- synth-status: GET, params in query string, no body
|
||||||
UPDATE uapi SET httpmethod='GET', data=NULL, path='/synth/api/synth-status?task_id={{task_id}}' WHERE id='uapi_ktv_synth_status';
|
UPDATE uapi SET httpmethod='GET', data=NULL, path='/synth/api/synth-status?task_id={{task_id}}' WHERE id='uapi_ktv_synth_status';
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user