diff --git a/bin/backend_accounting.py b/bin/backend_accounting.py index df16f825..91c52558 100644 --- a/bin/backend_accounting.py +++ b/bin/backend_accounting.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -独立运行的LLM后台计费程序。 -从 sage.py 的 llmage 模块中提取,避免多进程模式下重复运行。 +独立运行的产品后台计费程序。 +产品记账已从 llmage 迁移到 product_management 模块。 """ import os import sys @@ -25,16 +25,13 @@ from llmage.init import load_llmage from pricing.init import load_pricing from discount.init import load_discount from dapi.init import load_dapi +from product_management import get_manager # 初始化配置 p = ProgramPath() config = getConfig(NS={'workdir': os.getcwd(), 'ProgramPath': p}) DBPools(config.databases) -# 导入 llmage 的计费函数 -from llmage.accounting import ( - backend_accounting -) def get_module_dbname(m): return 'sage' @@ -62,8 +59,11 @@ def main(): load_pricing() load_discount() load_dapi() + load_llmage() + + manager = get_manager() try: - loop.run_until_complete(backend_accounting()) + loop.run_until_complete(manager.backend_accounting()) except asyncio.CancelledError: pass finally: diff --git a/scripts/demucs-status.dspy b/scripts/demucs-status.dspy index 72de3cff..aa8c9f2e 100644 --- a/scripts/demucs-status.dspy +++ b/scripts/demucs-status.dspy @@ -1,54 +1,29 @@ # Demucs 任务状态查询 -# 部署到: /data/ymq/demucs-service/app/api/demucs-status.dspy # GET /demucs/api/demucs-status?task_id=xxx -import json - task_id = params_kw.task_id if not task_id: return {"error": "task_id is required"} env = request._run_ns longtasks = env.longtasks +if not longtasks: + return {"error": "longtasks not available"} -# longtasks 内部通过 Redis 存储结果,key 格式: {queue_name}:result:{task_id} -import redis.asyncio as redis -r = redis.Redis(host='127.0.0.1', port=6379, db=0, decode_responses=True) +task = await longtasks.get_redis_task(task_id) +if not task or not task.get("created_at"): + return {"task_id": task_id, "status": "not_found"} -# 尝试获取结果 -result_key = f"demucs:result:{task_id}" -raw = await r.get(result_key) +status = task.get("status", "unknown") +result = {"task_id": task_id, "status": status} -if raw: - data = json.loads(raw) - return { - "task_id": task_id, - "status": "SUCCEEDED", - "vocals_url": data.get("vocals_path", ""), - "accompaniment_url": data.get("accompaniment_path", ""), - "duration": data.get("duration", 0), - "usage": data.get("usage", {"次": 1}), - } +if status == "SUCCEEDED": + data = task.get("result", {}) + result["vocals_url"] = data.get("vocals_path", "") + result["accompaniment_url"] = data.get("accompaniment_path", "") + result["duration"] = data.get("duration", 0) + # worker 须在 result 中包含 usage 字段 + result["usage"] = data.get("usage", {"audio_seconds": data.get("duration", 0)}) +elif status == "FAILED": + result["error"] = task.get("error", str(task.get("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"} +return result diff --git a/scripts/demucs_worker_usage_fix.py b/scripts/demucs_worker_usage_fix.py new file mode 100644 index 00000000..d6501a7d --- /dev/null +++ b/scripts/demucs_worker_usage_fix.py @@ -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)} diff --git a/scripts/ktv_uapi_migration_p1_uapiio.sql b/scripts/ktv_uapi_migration_p1_uapiio.sql index 1e99ee4e..6950755a 100644 --- a/scripts/ktv_uapi_migration_p1_uapiio.sql +++ b/scripts/ktv_uapi_migration_p1_uapiio.sql @@ -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":"场景类型"}}' ) 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 ( 'ktv_synth_status_io', 'KTV合成状态', '查询音乐合成任务状态', diff --git a/scripts/ktv_uapi_migration_p2_uapi.sql b/scripts/ktv_uapi_migration_p2_uapi.sql index 9fc823ab..b7cac99a 100644 --- a/scripts/ktv_uapi_migration_p2_uapi.sql +++ b/scripts/ktv_uapi_migration_p2_uapi.sql @@ -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%}', ioid='ktv_songrate_evaluate_io' WHERE id='uapi_ktv_songrate_evaluate'; --- 9. 音乐合成 (async提交) -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) +-- 9. 合成状态查询 (sync) UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}', 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%}', @@ -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'; -- 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'; -- ppid (v1/models 过滤要求 ppid IS NOT NULL) diff --git a/scripts/ktv_uapi_migration_p4_pricing.sql b/scripts/ktv_uapi_migration_p4_pricing.sql index 6269872e..a4e8f841 100644 --- a/scripts/ktv_uapi_migration_p4_pricing.sql +++ b/scripts/ktv_uapi_migration_p4_pricing.sql @@ -13,7 +13,7 @@ INSERT INTO pricing_program (id,providerid,name) VALUES ('pp_ktv_subtitle','FZoJv7EUEdKL3pUt0BQ5S','KTV-字幕渲染'), ('pp_ktv_merge','FZoJv7EUEdKL3pUt0BQ5S','KTV-视频合并'), ('pp_ktv_songrate','FZoJv7EUEdKL3pUt0BQ5S','KTV-歌曲评分'), -('pp_ktv_synth','FZoJv7EUEdKL3pUt0BQ5S','KTV-音乐合成'), + ('pp_ktv_synth_status','FZoJv7EUEdKL3pUt0BQ5S','KTV-合成状态'), ('pp_ktv_realesrgan','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_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_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_realesrgan' WHERE id='pt_ktv_realesrgan_upscale'; 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_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_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_realesrgan' WHERE llmid='llm_ktv_realesrgan_upscale'; UPDATE llm_api_map SET ppid='pp_ktv_realesrgan_status' WHERE llmid='llm_ktv_realesrgan_status'; diff --git a/scripts/ktv_uapi_migration_p5_datafix.sql b/scripts/ktv_uapi_migration_p5_datafix.sql index 96ceed8c..2aa1cf07 100644 --- a/scripts/ktv_uapi_migration_p5_datafix.sql +++ b/scripts/ktv_uapi_migration_p5_datafix.sql @@ -27,9 +27,6 @@ UPDATE uapi SET data='{%set c=joiner(",")%}{{%if video_file%}{{c()}}"video_url": -- songrate: audio_file→audio_path 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 UPDATE uapi SET httpmethod='GET', data=NULL, path='/synth/api/synth-status?task_id={{task_id}}' WHERE id='uapi_ktv_synth_status';