Copy disabled (too large)
Download .txt
Showing preview only (11,060K chars total). Download the full file to get everything.
Repository: ace-step/ACE-Step-1.5
Branch: main
Commit: 00f514af36a9
Files: 1148
Total size: 10.3 MB
Directory structure:
gitextract_6lqx4nhl/
├── .claude/
│ └── skills/
│ ├── acestep/
│ │ ├── SKILL.md
│ │ ├── api-reference.md
│ │ └── scripts/
│ │ ├── acestep.sh
│ │ └── config.example.json
│ ├── acestep-docs/
│ │ ├── SKILL.md
│ │ ├── api/
│ │ │ ├── API.md
│ │ │ └── Openrouter_API.md
│ │ ├── getting-started/
│ │ │ ├── ABOUT.md
│ │ │ ├── README.md
│ │ │ └── Tutorial.md
│ │ └── guides/
│ │ ├── ENVIRONMENT_SETUP.md
│ │ ├── GPU_COMPATIBILITY.md
│ │ ├── GRADIO_GUIDE.md
│ │ ├── INFERENCE.md
│ │ ├── SCRIPT_CONFIGURATION.md
│ │ └── UPDATE_AND_BACKUP.md
│ ├── acestep-lyrics-transcription/
│ │ ├── SKILL.md
│ │ └── scripts/
│ │ ├── acestep-lyrics-transcription.sh
│ │ └── config.example.json
│ ├── acestep-simplemv/
│ │ ├── SKILL.md
│ │ └── scripts/
│ │ ├── package.json
│ │ ├── remotion.config.ts
│ │ ├── render-mv.sh
│ │ ├── render.mjs
│ │ ├── render.sh
│ │ ├── src/
│ │ │ ├── AudioVisualization.tsx
│ │ │ ├── Root.tsx
│ │ │ ├── index.ts
│ │ │ ├── parseLrc.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── acestep-songwriting/
│ │ └── SKILL.md
│ └── acestep-thumbnail/
│ ├── SKILL.md
│ └── scripts/
│ ├── acestep-thumbnail.sh
│ └── config.example.json
├── .dockerignore
├── .editorconfig
├── .githooks/
│ └── pre-push
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── codeql-config.yml
│ ├── copilot-instructions.md
│ └── workflows/
│ ├── close-inactive-issues.yml
│ ├── codeql.yml
│ └── docs.yml
├── .gitignore
├── AGENTS.md
├── CONTRIBUTING.md
├── Dockerfile.jetson
├── LICENSE
├── README-XPU.md
├── README.md
├── SECURITY.md
├── acestep/
│ ├── __init__.py
│ ├── acestep_v15_pipeline.py
│ ├── api/
│ │ ├── __init__.py
│ │ ├── http/
│ │ │ ├── __init__.py
│ │ │ ├── audio_route.py
│ │ │ ├── audio_route_http_test.py
│ │ │ ├── audio_route_test.py
│ │ │ ├── auth.py
│ │ │ ├── auth_test.py
│ │ │ ├── lora_routes.py
│ │ │ ├── lora_routes_http_test.py
│ │ │ ├── lora_routes_test.py
│ │ │ ├── model_init_service.py
│ │ │ ├── model_init_service_test.py
│ │ │ ├── model_service_routes.py
│ │ │ ├── model_service_routes_http_test.py
│ │ │ ├── model_service_routes_test.py
│ │ │ ├── query_result_route.py
│ │ │ ├── query_result_route_http_test.py
│ │ │ ├── query_result_route_test.py
│ │ │ ├── query_result_service.py
│ │ │ ├── reinitialize_route.py
│ │ │ ├── reinitialize_route_http_test.py
│ │ │ ├── reinitialize_route_test.py
│ │ │ ├── release_task_audio_paths.py
│ │ │ ├── release_task_audio_paths_test.py
│ │ │ ├── release_task_models.py
│ │ │ ├── release_task_models_test.py
│ │ │ ├── release_task_param_parser.py
│ │ │ ├── release_task_param_parser_test.py
│ │ │ ├── release_task_request_builder.py
│ │ │ ├── release_task_request_builder_test.py
│ │ │ ├── release_task_request_parser.py
│ │ │ ├── release_task_request_parser_test.py
│ │ │ ├── release_task_route.py
│ │ │ ├── release_task_route_http_test.py
│ │ │ ├── sample_format_routes.py
│ │ │ ├── sample_format_routes_http_test.py
│ │ │ └── sample_format_routes_test.py
│ │ ├── job_analysis_runtime.py
│ │ ├── job_analysis_runtime_test.py
│ │ ├── job_blocking_generation.py
│ │ ├── job_blocking_generation_test.py
│ │ ├── job_execution_runtime.py
│ │ ├── job_execution_runtime_test.py
│ │ ├── job_generation_runtime.py
│ │ ├── job_generation_runtime_test.py
│ │ ├── job_generation_setup.py
│ │ ├── job_generation_setup_test.py
│ │ ├── job_llm_preparation.py
│ │ ├── job_llm_preparation_test.py
│ │ ├── job_model_selection.py
│ │ ├── job_model_selection_test.py
│ │ ├── job_result_payload.py
│ │ ├── job_result_payload_test.py
│ │ ├── job_runtime_state.py
│ │ ├── job_runtime_state_test.py
│ │ ├── jobs/
│ │ │ ├── __init__.py
│ │ │ ├── local_cache_updates.py
│ │ │ ├── local_cache_updates_test.py
│ │ │ ├── models.py
│ │ │ ├── store.py
│ │ │ ├── store_test.py
│ │ │ ├── test_fakes.py
│ │ │ ├── worker_loops.py
│ │ │ └── worker_loops_test.py
│ │ ├── lifespan_runtime.py
│ │ ├── lifespan_runtime_test.py
│ │ ├── llm_generation_inputs.py
│ │ ├── llm_readiness.py
│ │ ├── log_capture.py
│ │ ├── log_capture_test.py
│ │ ├── model_download.py
│ │ ├── model_download_test.py
│ │ ├── route_setup.py
│ │ ├── route_setup_test.py
│ │ ├── runtime_helpers.py
│ │ ├── runtime_helpers_test.py
│ │ ├── server_cli.py
│ │ ├── server_cli_test.py
│ │ ├── server_utils.py
│ │ ├── server_utils_test.py
│ │ ├── startup_llm_init.py
│ │ ├── startup_llm_init_test.py
│ │ ├── startup_model_init.py
│ │ ├── startup_model_init_test.py
│ │ ├── train_api_dataset_auto_label_async_route.py
│ │ ├── train_api_dataset_auto_label_routes.py
│ │ ├── train_api_dataset_auto_label_routes_http_test.py
│ │ ├── train_api_dataset_auto_label_status_route.py
│ │ ├── train_api_dataset_auto_label_sync_route.py
│ │ ├── train_api_dataset_models.py
│ │ ├── train_api_dataset_models_test.py
│ │ ├── train_api_dataset_preprocess_routes.py
│ │ ├── train_api_dataset_preprocess_routes_http_test.py
│ │ ├── train_api_dataset_sample_routes.py
│ │ ├── train_api_dataset_sample_routes_http_test.py
│ │ ├── train_api_dataset_scan_load_routes.py
│ │ ├── train_api_dataset_scan_load_routes_http_test.py
│ │ ├── train_api_dataset_service.py
│ │ ├── train_api_dataset_service_http_test.py
│ │ ├── train_api_dataset_status_routes.py
│ │ ├── train_api_dataset_status_routes_http_test.py
│ │ ├── train_api_lokr_start_route.py
│ │ ├── train_api_lora_start_route.py
│ │ ├── train_api_models.py
│ │ ├── train_api_runtime.py
│ │ ├── train_api_service.py
│ │ ├── train_api_service_http_test.py
│ │ ├── worker_runtime.py
│ │ └── worker_runtime_test.py
│ ├── api_server.py
│ ├── audio_utils.py
│ ├── audio_utils_test.py
│ ├── audio_utils_uuid_test.py
│ ├── cli_args.py
│ ├── cli_args_test.py
│ ├── constants.py
│ ├── constrained_logits_processor.py
│ ├── core/
│ │ ├── __init__.py
│ │ ├── audio/
│ │ │ └── __init__.py
│ │ ├── generation/
│ │ │ ├── __init__.py
│ │ │ └── handler/
│ │ │ ├── __init__.py
│ │ │ ├── audio_codes.py
│ │ │ ├── batch_prep.py
│ │ │ ├── conditioning_batch.py
│ │ │ ├── conditioning_batch_test.py
│ │ │ ├── conditioning_embed.py
│ │ │ ├── conditioning_embed_test.py
│ │ │ ├── conditioning_masks.py
│ │ │ ├── conditioning_masks_test.py
│ │ │ ├── conditioning_target.py
│ │ │ ├── conditioning_text.py
│ │ │ ├── cover_noise_strength_forwarding_test.py
│ │ │ ├── diffusion.py
│ │ │ ├── diffusion_test.py
│ │ │ ├── generate_music.py
│ │ │ ├── generate_music_decode.py
│ │ │ ├── generate_music_decode_test.py
│ │ │ ├── generate_music_execute.py
│ │ │ ├── generate_music_execute_test.py
│ │ │ ├── generate_music_payload.py
│ │ │ ├── generate_music_payload_test.py
│ │ │ ├── generate_music_request.py
│ │ │ ├── generate_music_request_test.py
│ │ │ ├── generate_music_test.py
│ │ │ ├── init_service.py
│ │ │ ├── init_service_catalog.py
│ │ │ ├── init_service_downloads.py
│ │ │ ├── init_service_loader.py
│ │ │ ├── init_service_loader_components.py
│ │ │ ├── init_service_memory_basic.py
│ │ │ ├── init_service_memory_transfer.py
│ │ │ ├── init_service_offload_context.py
│ │ │ ├── init_service_orchestrator.py
│ │ │ ├── init_service_setup.py
│ │ │ ├── init_service_test.py
│ │ │ ├── io_audio.py
│ │ │ ├── io_audio_test.py
│ │ │ ├── lora/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── adapter_discovery.py
│ │ │ │ ├── controls.py
│ │ │ │ ├── controls_test.py
│ │ │ │ ├── lifecycle.py
│ │ │ │ ├── lifecycle_test.py
│ │ │ │ ├── registry_builder.py
│ │ │ │ ├── registry_state.py
│ │ │ │ └── scale_apply.py
│ │ │ ├── lora_integration_test.py
│ │ │ ├── lora_manager.py
│ │ │ ├── lyric_alignment_common.py
│ │ │ ├── lyric_alignment_test.py
│ │ │ ├── lyric_score.py
│ │ │ ├── lyric_timestamp.py
│ │ │ ├── memory_utils.py
│ │ │ ├── metadata_utils.py
│ │ │ ├── mlx_dit_init.py
│ │ │ ├── mlx_dit_init_test.py
│ │ │ ├── mlx_vae_decode_native.py
│ │ │ ├── mlx_vae_encode_native.py
│ │ │ ├── mlx_vae_init.py
│ │ │ ├── mlx_vae_init_test.py
│ │ │ ├── mlx_vae_native_test.py
│ │ │ ├── padding_utils.py
│ │ │ ├── progress.py
│ │ │ ├── progress_project_root_test.py
│ │ │ ├── prompt_utils.py
│ │ │ ├── reference_audio_validation_test.py
│ │ │ ├── repaint_step_injection.py
│ │ │ ├── repaint_step_injection_test.py
│ │ │ ├── repaint_waveform_splice.py
│ │ │ ├── repaint_waveform_splice_test.py
│ │ │ ├── resolve_repaint_config_test.py
│ │ │ ├── service_generate.py
│ │ │ ├── service_generate_execute.py
│ │ │ ├── service_generate_execute_test.py
│ │ │ ├── service_generate_outputs.py
│ │ │ ├── service_generate_request.py
│ │ │ ├── service_generate_request_test.py
│ │ │ ├── service_generate_test.py
│ │ │ ├── task_utils.py
│ │ │ ├── task_utils_test.py
│ │ │ ├── training_preset.py
│ │ │ ├── training_preset_test.py
│ │ │ ├── vae_decode.py
│ │ │ ├── vae_decode_chunks.py
│ │ │ ├── vae_decode_chunks_test.py
│ │ │ ├── vae_decode_mixin_test.py
│ │ │ ├── vae_decode_test_helpers.py
│ │ │ ├── vae_encode.py
│ │ │ ├── vae_encode_chunks.py
│ │ │ └── vae_encode_test.py
│ │ ├── llm/
│ │ │ └── __init__.py
│ │ ├── lora/
│ │ │ ├── __init__.py
│ │ │ ├── introspection.py
│ │ │ ├── registry.py
│ │ │ ├── scaling.py
│ │ │ ├── service.py
│ │ │ └── service_test.py
│ │ ├── scoring/
│ │ │ ├── __init__.py
│ │ │ ├── _dtw.py
│ │ │ ├── dit_alignment.py
│ │ │ ├── dit_score.py
│ │ │ ├── lm_score.py
│ │ │ └── scoring_test.py
│ │ └── system/
│ │ └── __init__.py
│ ├── dataset/
│ │ ├── __init__.py
│ │ ├── builder/
│ │ │ └── __init__.py
│ │ └── runtime/
│ │ └── __init__.py
│ ├── dataset_handler.py
│ ├── debug_utils.py
│ ├── genres_vocab.txt
│ ├── gpu_config.py
│ ├── gpu_config_effective_free_vram_test.py
│ ├── handler.py
│ ├── inference.py
│ ├── launcher_compat.py
│ ├── launcher_compat_test.py
│ ├── launcher_legacy_torch_fix_test.py
│ ├── llm_backend_compat.py
│ ├── llm_backend_compat_test.py
│ ├── llm_inference.py
│ ├── llm_inference_cache_cleanup_test.py
│ ├── llm_inference_cfg_fixes_test.py
│ ├── llm_inference_dist_cleanup_test.py
│ ├── llm_inference_enforce_eager_test.py
│ ├── local_cache.py
│ ├── local_cache_thread_safety_test.py
│ ├── model_downloader.py
│ ├── model_downloader_test.py
│ ├── models/
│ │ ├── __init__.py
│ │ ├── base/
│ │ │ ├── __init__.py
│ │ │ ├── apg_guidance.py
│ │ │ ├── configuration_acestep_v15.py
│ │ │ └── modeling_acestep_v15_base.py
│ │ ├── mlx/
│ │ │ ├── __init__.py
│ │ │ ├── dit_convert.py
│ │ │ ├── dit_generate.py
│ │ │ ├── dit_model.py
│ │ │ ├── vae_convert.py
│ │ │ └── vae_model.py
│ │ ├── sft/
│ │ │ ├── __init__.py
│ │ │ ├── apg_guidance.py
│ │ │ ├── configuration_acestep_v15.py
│ │ │ └── modeling_acestep_v15_base.py
│ │ └── turbo/
│ │ ├── __init__.py
│ │ ├── configuration_acestep_v15.py
│ │ └── modeling_acestep_v15_turbo.py
│ ├── null_duration_fixes_test.py
│ ├── openrouter_adapter.py
│ ├── openrouter_models.py
│ ├── text2music_src_audio_test.py
│ ├── third_parts/
│ │ └── nano-vllm/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── bench.py
│ │ ├── example.py
│ │ ├── nanovllm/
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── distributed.py
│ │ │ ├── engine/
│ │ │ │ ├── block_manager.py
│ │ │ │ ├── llm_engine.py
│ │ │ │ ├── model_runner.py
│ │ │ │ ├── scheduler.py
│ │ │ │ └── sequence.py
│ │ │ ├── layers/
│ │ │ │ ├── activation.py
│ │ │ │ ├── attention.py
│ │ │ │ ├── embed_head.py
│ │ │ │ ├── layernorm.py
│ │ │ │ ├── linear.py
│ │ │ │ ├── rotary_embedding.py
│ │ │ │ └── sampler.py
│ │ │ ├── llm.py
│ │ │ ├── models/
│ │ │ │ └── qwen3.py
│ │ │ ├── sampling_params.py
│ │ │ └── utils/
│ │ │ ├── compat.py
│ │ │ ├── compat_test.py
│ │ │ ├── context.py
│ │ │ └── loader.py
│ │ └── pyproject.toml
│ ├── training/
│ │ ├── __init__.py
│ │ ├── configs.py
│ │ ├── data_module.py
│ │ ├── data_module_test.py
│ │ ├── dataset_builder.py
│ │ ├── dataset_builder_modules/
│ │ │ ├── __init__.py
│ │ │ ├── audio_io.py
│ │ │ ├── builder.py
│ │ │ ├── core.py
│ │ │ ├── csv_metadata.py
│ │ │ ├── dataframe.py
│ │ │ ├── label_all.py
│ │ │ ├── label_single.py
│ │ │ ├── label_utils.py
│ │ │ ├── metadata.py
│ │ │ ├── models.py
│ │ │ ├── preprocess.py
│ │ │ ├── preprocess_audio.py
│ │ │ ├── preprocess_context.py
│ │ │ ├── preprocess_encoder.py
│ │ │ ├── preprocess_lyrics.py
│ │ │ ├── preprocess_manifest.py
│ │ │ ├── preprocess_text.py
│ │ │ ├── preprocess_utils.py
│ │ │ ├── preprocess_vae.py
│ │ │ ├── scan.py
│ │ │ ├── serialization.py
│ │ │ └── update_sample.py
│ │ ├── lokr_utils.py
│ │ ├── lora_checkpoint.py
│ │ ├── lora_injection.py
│ │ ├── lora_utils.py
│ │ ├── path_safety.py
│ │ ├── test_lora_utils.py
│ │ └── trainer.py
│ ├── training_v2/
│ │ ├── __init__.py
│ │ ├── cli/
│ │ │ ├── __init__.py
│ │ │ ├── args.py
│ │ │ ├── common.py
│ │ │ ├── config_builder.py
│ │ │ ├── train_fixed.py
│ │ │ ├── train_vanilla.py
│ │ │ └── validation.py
│ │ ├── configs.py
│ │ ├── estimate.py
│ │ ├── fixed_lora_module.py
│ │ ├── gpu_utils.py
│ │ ├── make_test_fixtures.py
│ │ ├── model_discovery.py
│ │ ├── model_loader.py
│ │ ├── optim.py
│ │ ├── preprocess.py
│ │ ├── preprocess_discovery.py
│ │ ├── preprocess_prompt.py
│ │ ├── preprocess_vae.py
│ │ ├── presets/
│ │ │ ├── high_quality.json
│ │ │ ├── quick_test.json
│ │ │ ├── recommended.json
│ │ │ ├── vram_12gb.json
│ │ │ ├── vram_16gb.json
│ │ │ ├── vram_24gb_plus.json
│ │ │ └── vram_8gb.json
│ │ ├── settings.py
│ │ ├── tensorboard_utils.py
│ │ ├── timestep_sampling.py
│ │ ├── trainer_basic_loop.py
│ │ ├── trainer_fixed.py
│ │ ├── trainer_helpers.py
│ │ ├── trainer_helpers_test.py
│ │ ├── trainer_vanilla.py
│ │ └── ui/
│ │ ├── __init__.py
│ │ ├── banner.py
│ │ ├── config_panel.py
│ │ ├── errors.py
│ │ ├── flows.py
│ │ ├── flows_common.py
│ │ ├── flows_estimate.py
│ │ ├── flows_preprocess.py
│ │ ├── flows_setup.py
│ │ ├── flows_train.py
│ │ ├── flows_train_steps.py
│ │ ├── gpu_monitor.py
│ │ ├── help_formatter.py
│ │ ├── presets.py
│ │ ├── progress.py
│ │ ├── prompt_helpers.py
│ │ ├── summary.py
│ │ ├── wizard.py
│ │ └── wizard_menus.py
│ └── ui/
│ ├── __init__.py
│ ├── gradio/
│ │ ├── __init__.py
│ │ ├── api/
│ │ │ ├── __init__.py
│ │ │ ├── api_routes.py
│ │ │ ├── api_routes_resource_test.py
│ │ │ └── api_routes_thread_safety_test.py
│ │ ├── events/
│ │ │ ├── __init__.py
│ │ │ ├── generation/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── llm_action_params.py
│ │ │ │ ├── llm_actions.py
│ │ │ │ ├── llm_analysis_actions.py
│ │ │ │ ├── llm_format_actions.py
│ │ │ │ ├── llm_sample_actions.py
│ │ │ │ ├── metadata_loading.py
│ │ │ │ ├── mode_ui.py
│ │ │ │ ├── mode_ui_helpers.py
│ │ │ │ ├── mode_ui_test.py
│ │ │ │ ├── model_config.py
│ │ │ │ ├── model_config_test.py
│ │ │ │ ├── service_init.py
│ │ │ │ ├── service_init_test.py
│ │ │ │ ├── ui_helpers.py
│ │ │ │ └── validation.py
│ │ │ ├── generation_handlers.py
│ │ │ ├── generation_handlers_test.py
│ │ │ ├── results/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _batch_management_test_support.py
│ │ │ │ ├── audio_playback_updates.py
│ │ │ │ ├── audio_playback_updates_test.py
│ │ │ │ ├── audio_transfer.py
│ │ │ │ ├── batch_management.py
│ │ │ │ ├── batch_management_background.py
│ │ │ │ ├── batch_management_background_test.py
│ │ │ │ ├── batch_management_helpers.py
│ │ │ │ ├── batch_management_helpers_test.py
│ │ │ │ ├── batch_management_test.py
│ │ │ │ ├── batch_management_wrapper.py
│ │ │ │ ├── batch_navigation.py
│ │ │ │ ├── batch_navigation_test.py
│ │ │ │ ├── batch_queue.py
│ │ │ │ ├── batch_queue_test.py
│ │ │ │ ├── generation_info.py
│ │ │ │ ├── generation_info_test.py
│ │ │ │ ├── generation_progress.py
│ │ │ │ ├── lrc_utils.py
│ │ │ │ ├── lrc_utils_test.py
│ │ │ │ └── scoring.py
│ │ │ ├── results_handlers.py
│ │ │ ├── results_handlers_facade_test.py
│ │ │ ├── training/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── dataset_ops.py
│ │ │ │ ├── dataset_ops_test.py
│ │ │ │ ├── lokr_training.py
│ │ │ │ ├── lora_training.py
│ │ │ │ ├── preprocess.py
│ │ │ │ ├── preprocess_test.py
│ │ │ │ ├── training_facade_test.py
│ │ │ │ ├── training_utils.py
│ │ │ │ └── training_utils_test.py
│ │ │ ├── training_handlers.py
│ │ │ └── wiring/
│ │ │ ├── __init__.py
│ │ │ ├── ast_test_utils.py
│ │ │ ├── context.py
│ │ │ ├── context_test.py
│ │ │ ├── decomposition_contract_generation_test.py
│ │ │ ├── decomposition_contract_helpers.py
│ │ │ ├── decomposition_contract_training_test.py
│ │ │ ├── docstring_coverage_test.py
│ │ │ ├── generation_batch_navigation_wiring.py
│ │ │ ├── generation_metadata_file_wiring.py
│ │ │ ├── generation_metadata_file_wiring_test.py
│ │ │ ├── generation_metadata_wiring.py
│ │ │ ├── generation_mode_wiring.py
│ │ │ ├── generation_run_wiring.py
│ │ │ ├── generation_service_wiring.py
│ │ │ ├── generation_service_wiring_test.py
│ │ │ ├── generation_text_format_wiring.py
│ │ │ ├── results_aux_wiring.py
│ │ │ ├── results_display_wiring.py
│ │ │ ├── results_display_wiring_test.py
│ │ │ ├── training_dataset_builder_wiring.py
│ │ │ ├── training_dataset_preprocess_wiring.py
│ │ │ ├── training_lokr_wiring.py
│ │ │ └── training_run_wiring.py
│ │ ├── help_content.py
│ │ ├── help_content_i18n_test.py
│ │ ├── help_content_md_test.py
│ │ ├── help_content_misc_test.py
│ │ ├── help_content_test.py
│ │ ├── help_content_test_helpers.py
│ │ ├── i18n/
│ │ │ ├── __init__.py
│ │ │ ├── en.json
│ │ │ ├── he.json
│ │ │ ├── i18n.py
│ │ │ ├── i18n_thread_safety_test.py
│ │ │ ├── ja.json
│ │ │ └── zh.json
│ │ └── interfaces/
│ │ ├── __init__.py
│ │ ├── audio_player_preferences.js
│ │ ├── audio_player_preferences.py
│ │ ├── audio_player_preferences_test.py
│ │ ├── dataset.py
│ │ ├── generation.py
│ │ ├── generation_advanced_dit_controls.py
│ │ ├── generation_advanced_output_controls.py
│ │ ├── generation_advanced_primary_controls.py
│ │ ├── generation_advanced_settings.py
│ │ ├── generation_contract_ast_utils.py
│ │ ├── generation_decomposition_contract_test.py
│ │ ├── generation_defaults.py
│ │ ├── generation_service_config.py
│ │ ├── generation_service_config_rows.py
│ │ ├── generation_service_config_rows_test.py
│ │ ├── generation_service_config_toggles.py
│ │ ├── generation_tab_generate_controls.py
│ │ ├── generation_tab_optional_controls.py
│ │ ├── generation_tab_optional_controls_test.py
│ │ ├── generation_tab_primary_controls.py
│ │ ├── generation_tab_runtime_controls.py
│ │ ├── generation_tab_secondary_controls.py
│ │ ├── generation_tab_section.py
│ │ ├── generation_tab_simple_controls.py
│ │ ├── generation_tab_source_controls.py
│ │ ├── result.py
│ │ ├── training.py
│ │ ├── training_contract_ast_utils.py
│ │ ├── training_dataset_builder_tab.py
│ │ ├── training_dataset_tab_label_preview.py
│ │ ├── training_dataset_tab_save_preprocess.py
│ │ ├── training_dataset_tab_scan_settings.py
│ │ ├── training_decomposition_contract_test.py
│ │ ├── training_lokr_tab.py
│ │ ├── training_lokr_tab_dataset.py
│ │ ├── training_lokr_tab_run_export.py
│ │ ├── training_lora_tab.py
│ │ ├── training_lora_tab_dataset.py
│ │ └── training_lora_tab_run_export.py
│ └── streamlit/
│ ├── .gitignore
│ ├── .streamlit/
│ │ ├── config.toml
│ │ └── secrets.toml
│ ├── INSTALL.md
│ ├── PROJECT_SUMMARY.md
│ ├── QUICKSTART.md
│ ├── README.md
│ ├── components/
│ │ ├── __init__.py
│ │ ├── audio_player.py
│ │ ├── batch_generator.py
│ │ ├── dashboard.py
│ │ ├── editor.py
│ │ ├── editor_audio_picker.py
│ │ ├── editor_runner.py
│ │ ├── editor_tasks.py
│ │ ├── editor_waveform.py
│ │ ├── generation_wizard.py
│ │ └── settings_panel.py
│ ├── config.py
│ ├── main.py
│ ├── requirements.txt
│ ├── run.bat
│ ├── run.sh
│ └── utils/
│ ├── __init__.py
│ ├── audio_utils.py
│ ├── cache.py
│ └── project_manager.py
├── check_update.bat
├── check_update.sh
├── cli.py
├── close_api_server.sh
├── docker-compose.jetson.yml
├── docs/
│ ├── .vitepress/
│ │ ├── config.mts
│ │ └── theme/
│ │ ├── custom.css
│ │ └── index.ts
│ ├── en/
│ │ ├── ACE-Step1.5-Rocm-Manual-Linux.md
│ │ ├── API.md
│ │ ├── BENCHMARK.md
│ │ ├── CLI.md
│ │ ├── GPU_COMPATIBILITY.md
│ │ ├── GPU_TROUBLESHOOTING.md
│ │ ├── GRADIO_GUIDE.md
│ │ ├── INFERENCE.md
│ │ ├── INSTALL.md
│ │ ├── LoRA_Training_Tutorial.md
│ │ ├── Openrouter_API_DOC.md
│ │ ├── Tutorial.md
│ │ ├── VST3_BACKEND_CONTRACT.md
│ │ ├── VST3_MVP.md
│ │ ├── VST3_SETUP.md
│ │ ├── ace_step_musicians_guide.md
│ │ ├── index.md
│ │ └── studio.md
│ ├── index.md
│ ├── ja/
│ │ ├── API.md
│ │ ├── GPU_COMPATIBILITY.md
│ │ ├── GRADIO_GUIDE.md
│ │ ├── INFERENCE.md
│ │ ├── INSTALL.md
│ │ ├── LoRA_Training_Tutorial.md
│ │ ├── Openrouter_API_DOC.md
│ │ ├── Tutorial.md
│ │ └── index.md
│ ├── ko/
│ │ ├── API.md
│ │ ├── GPU_COMPATIBILITY.md
│ │ ├── GRADIO_GUIDE.md
│ │ ├── INFERENCE.md
│ │ ├── LoRA_Training_Tutorial.md
│ │ ├── Openrouter_API_DOC.md
│ │ ├── Tutorial.md
│ │ └── index.md
│ ├── sidestep/
│ │ ├── Dataset Preparation.md
│ │ ├── End-to-End Tutorial.md
│ │ ├── Estimation Guide.md
│ │ ├── Getting Started.md
│ │ ├── Model Management.md
│ │ ├── ObsidianREADME.md
│ │ ├── Preset Management.md
│ │ ├── RepositoryREADME.md
│ │ ├── Shift and Timestep Sampling.md
│ │ ├── The Settings Wizard.md
│ │ ├── Training Guide.md
│ │ ├── Using Your Adapter.md
│ │ ├── VRAM Optimization Guide.md
│ │ └── Windows Notes.md
│ └── zh/
│ ├── API.md
│ ├── BENCHMARK.md
│ ├── GPU_COMPATIBILITY.md
│ ├── GRADIO_GUIDE.md
│ ├── INFERENCE.md
│ ├── INSTALL.md
│ ├── LoRA_Training_Tutorial.md
│ ├── Openrouter_API_DOC.md
│ ├── Tutorial.md
│ └── index.md
├── examples/
│ ├── simple_mode/
│ │ ├── example_01.json
│ │ ├── example_02.json
│ │ ├── example_03.json
│ │ ├── example_04.json
│ │ ├── example_05.json
│ │ ├── example_06.json
│ │ ├── example_07.json
│ │ ├── example_08.json
│ │ ├── example_09.json
│ │ ├── example_10.json
│ │ ├── example_100.json
│ │ ├── example_101.json
│ │ ├── example_102.json
│ │ ├── example_103.json
│ │ ├── example_104.json
│ │ ├── example_105.json
│ │ ├── example_106.json
│ │ ├── example_107.json
│ │ ├── example_108.json
│ │ ├── example_109.json
│ │ ├── example_11.json
│ │ ├── example_110.json
│ │ ├── example_111.json
│ │ ├── example_112.json
│ │ ├── example_113.json
│ │ ├── example_114.json
│ │ ├── example_115.json
│ │ ├── example_116.json
│ │ ├── example_117.json
│ │ ├── example_118.json
│ │ ├── example_119.json
│ │ ├── example_12.json
│ │ ├── example_120.json
│ │ ├── example_121.json
│ │ ├── example_122.json
│ │ ├── example_123.json
│ │ ├── example_124.json
│ │ ├── example_125.json
│ │ ├── example_126.json
│ │ ├── example_127.json
│ │ ├── example_128.json
│ │ ├── example_129.json
│ │ ├── example_13.json
│ │ ├── example_130.json
│ │ ├── example_131.json
│ │ ├── example_132.json
│ │ ├── example_133.json
│ │ ├── example_134.json
│ │ ├── example_135.json
│ │ ├── example_136.json
│ │ ├── example_137.json
│ │ ├── example_138.json
│ │ ├── example_139.json
│ │ ├── example_14.json
│ │ ├── example_140.json
│ │ ├── example_141.json
│ │ ├── example_142.json
│ │ ├── example_143.json
│ │ ├── example_144.json
│ │ ├── example_145.json
│ │ ├── example_146.json
│ │ ├── example_147.json
│ │ ├── example_148.json
│ │ ├── example_149.json
│ │ ├── example_15.json
│ │ ├── example_150.json
│ │ ├── example_151.json
│ │ ├── example_152.json
│ │ ├── example_153.json
│ │ ├── example_154.json
│ │ ├── example_155.json
│ │ ├── example_156.json
│ │ ├── example_157.json
│ │ ├── example_158.json
│ │ ├── example_159.json
│ │ ├── example_16.json
│ │ ├── example_160.json
│ │ ├── example_161.json
│ │ ├── example_162.json
│ │ ├── example_163.json
│ │ ├── example_164.json
│ │ ├── example_165.json
│ │ ├── example_166.json
│ │ ├── example_167.json
│ │ ├── example_168.json
│ │ ├── example_169.json
│ │ ├── example_17.json
│ │ ├── example_170.json
│ │ ├── example_171.json
│ │ ├── example_172.json
│ │ ├── example_173.json
│ │ ├── example_174.json
│ │ ├── example_175.json
│ │ ├── example_176.json
│ │ ├── example_177.json
│ │ ├── example_178.json
│ │ ├── example_179.json
│ │ ├── example_18.json
│ │ ├── example_180.json
│ │ ├── example_181.json
│ │ ├── example_182.json
│ │ ├── example_183.json
│ │ ├── example_184.json
│ │ ├── example_185.json
│ │ ├── example_186.json
│ │ ├── example_187.json
│ │ ├── example_188.json
│ │ ├── example_189.json
│ │ ├── example_19.json
│ │ ├── example_190.json
│ │ ├── example_191.json
│ │ ├── example_192.json
│ │ ├── example_193.json
│ │ ├── example_194.json
│ │ ├── example_195.json
│ │ ├── example_196.json
│ │ ├── example_197.json
│ │ ├── example_198.json
│ │ ├── example_199.json
│ │ ├── example_20.json
│ │ ├── example_200.json
│ │ ├── example_21.json
│ │ ├── example_22.json
│ │ ├── example_23.json
│ │ ├── example_24.json
│ │ ├── example_25.json
│ │ ├── example_26.json
│ │ ├── example_27.json
│ │ ├── example_28.json
│ │ ├── example_29.json
│ │ ├── example_30.json
│ │ ├── example_31.json
│ │ ├── example_32.json
│ │ ├── example_33.json
│ │ ├── example_34.json
│ │ ├── example_35.json
│ │ ├── example_36.json
│ │ ├── example_37.json
│ │ ├── example_38.json
│ │ ├── example_39.json
│ │ ├── example_40.json
│ │ ├── example_41.json
│ │ ├── example_42.json
│ │ ├── example_43.json
│ │ ├── example_44.json
│ │ ├── example_45.json
│ │ ├── example_46.json
│ │ ├── example_47.json
│ │ ├── example_48.json
│ │ ├── example_49.json
│ │ ├── example_50.json
│ │ ├── example_51.json
│ │ ├── example_52.json
│ │ ├── example_53.json
│ │ ├── example_54.json
│ │ ├── example_55.json
│ │ ├── example_56.json
│ │ ├── example_57.json
│ │ ├── example_58.json
│ │ ├── example_59.json
│ │ ├── example_60.json
│ │ ├── example_61.json
│ │ ├── example_62.json
│ │ ├── example_63.json
│ │ ├── example_64.json
│ │ ├── example_65.json
│ │ ├── example_66.json
│ │ ├── example_67.json
│ │ ├── example_68.json
│ │ ├── example_69.json
│ │ ├── example_70.json
│ │ ├── example_71.json
│ │ ├── example_72.json
│ │ ├── example_73.json
│ │ ├── example_74.json
│ │ ├── example_75.json
│ │ ├── example_76.json
│ │ ├── example_77.json
│ │ ├── example_78.json
│ │ ├── example_79.json
│ │ ├── example_80.json
│ │ ├── example_81.json
│ │ ├── example_82.json
│ │ ├── example_83.json
│ │ ├── example_84.json
│ │ ├── example_85.json
│ │ ├── example_86.json
│ │ ├── example_87.json
│ │ ├── example_88.json
│ │ ├── example_89.json
│ │ ├── example_90.json
│ │ ├── example_91.json
│ │ ├── example_92.json
│ │ ├── example_93.json
│ │ ├── example_94.json
│ │ ├── example_95.json
│ │ ├── example_96.json
│ │ ├── example_97.json
│ │ ├── example_98.json
│ │ └── example_99.json
│ └── text2music/
│ ├── example_01.json
│ ├── example_02.json
│ ├── example_03.json
│ ├── example_04.json
│ ├── example_05.json
│ ├── example_06.json
│ ├── example_07.json
│ ├── example_08.json
│ ├── example_09.json
│ ├── example_10.json
│ ├── example_100.json
│ ├── example_101.json
│ ├── example_102.json
│ ├── example_103.json
│ ├── example_104.json
│ ├── example_105.json
│ ├── example_106.json
│ ├── example_107.json
│ ├── example_108.json
│ ├── example_109.json
│ ├── example_11.json
│ ├── example_110.json
│ ├── example_111.json
│ ├── example_112.json
│ ├── example_113.json
│ ├── example_114.json
│ ├── example_115.json
│ ├── example_116.json
│ ├── example_117.json
│ ├── example_118.json
│ ├── example_119.json
│ ├── example_12.json
│ ├── example_120.json
│ ├── example_121.json
│ ├── example_122.json
│ ├── example_123.json
│ ├── example_124.json
│ ├── example_125.json
│ ├── example_126.json
│ ├── example_127.json
│ ├── example_128.json
│ ├── example_129.json
│ ├── example_13.json
│ ├── example_130.json
│ ├── example_131.json
│ ├── example_132.json
│ ├── example_133.json
│ ├── example_134.json
│ ├── example_135.json
│ ├── example_136.json
│ ├── example_137.json
│ ├── example_138.json
│ ├── example_139.json
│ ├── example_14.json
│ ├── example_140.json
│ ├── example_141.json
│ ├── example_142.json
│ ├── example_143.json
│ ├── example_144.json
│ ├── example_145.json
│ ├── example_146.json
│ ├── example_147.json
│ ├── example_148.json
│ ├── example_149.json
│ ├── example_15.json
│ ├── example_150.json
│ ├── example_151.json
│ ├── example_152.json
│ ├── example_153.json
│ ├── example_154.json
│ ├── example_155.json
│ ├── example_156.json
│ ├── example_157.json
│ ├── example_158.json
│ ├── example_159.json
│ ├── example_16.json
│ ├── example_160.json
│ ├── example_161.json
│ ├── example_162.json
│ ├── example_163.json
│ ├── example_164.json
│ ├── example_165.json
│ ├── example_166.json
│ ├── example_167.json
│ ├── example_168.json
│ ├── example_169.json
│ ├── example_17.json
│ ├── example_170.json
│ ├── example_171.json
│ ├── example_172.json
│ ├── example_173.json
│ ├── example_174.json
│ ├── example_175.json
│ ├── example_176.json
│ ├── example_177.json
│ ├── example_178.json
│ ├── example_179.json
│ ├── example_18.json
│ ├── example_180.json
│ ├── example_181.json
│ ├── example_182.json
│ ├── example_183.json
│ ├── example_184.json
│ ├── example_185.json
│ ├── example_186.json
│ ├── example_187.json
│ ├── example_188.json
│ ├── example_189.json
│ ├── example_19.json
│ ├── example_190.json
│ ├── example_191.json
│ ├── example_192.json
│ ├── example_193.json
│ ├── example_194.json
│ ├── example_195.json
│ ├── example_196.json
│ ├── example_197.json
│ ├── example_198.json
│ ├── example_199.json
│ ├── example_20.json
│ ├── example_200.json
│ ├── example_21.json
│ ├── example_22.json
│ ├── example_23.json
│ ├── example_24.json
│ ├── example_25.json
│ ├── example_26.json
│ ├── example_27.json
│ ├── example_28.json
│ ├── example_29.json
│ ├── example_30.json
│ ├── example_31.json
│ ├── example_32.json
│ ├── example_33.json
│ ├── example_34.json
│ ├── example_35.json
│ ├── example_36.json
│ ├── example_37.json
│ ├── example_38.json
│ ├── example_39.json
│ ├── example_40.json
│ ├── example_41.json
│ ├── example_42.json
│ ├── example_43.json
│ ├── example_44.json
│ ├── example_45.json
│ ├── example_46.json
│ ├── example_47.json
│ ├── example_48.json
│ ├── example_49.json
│ ├── example_50.json
│ ├── example_51.json
│ ├── example_52.json
│ ├── example_53.json
│ ├── example_54.json
│ ├── example_55.json
│ ├── example_56.json
│ ├── example_57.json
│ ├── example_58.json
│ ├── example_59.json
│ ├── example_60.json
│ ├── example_61.json
│ ├── example_62.json
│ ├── example_63.json
│ ├── example_64.json
│ ├── example_65.json
│ ├── example_66.json
│ ├── example_67.json
│ ├── example_68.json
│ ├── example_69.json
│ ├── example_70.json
│ ├── example_71.json
│ ├── example_72.json
│ ├── example_73.json
│ ├── example_74.json
│ ├── example_75.json
│ ├── example_76.json
│ ├── example_77.json
│ ├── example_78.json
│ ├── example_79.json
│ ├── example_80.json
│ ├── example_81.json
│ ├── example_82.json
│ ├── example_83.json
│ ├── example_84.json
│ ├── example_85.json
│ ├── example_86.json
│ ├── example_87.json
│ ├── example_88.json
│ ├── example_89.json
│ ├── example_90.json
│ ├── example_91.json
│ ├── example_92.json
│ ├── example_93.json
│ ├── example_94.json
│ ├── example_95.json
│ ├── example_96.json
│ ├── example_97.json
│ ├── example_98.json
│ └── example_99.json
├── generate_examples.py
├── install_uv.bat
├── install_uv.sh
├── merge_config.bat
├── merge_config.sh
├── openrouter/
│ ├── __init__.py
│ ├── client_test.py
│ ├── openrouter_api_server.py
│ └── stress_test.py
├── package.json
├── plugins/
│ └── acestep_vst3/
│ ├── CMakeLists.txt
│ ├── README.md
│ └── src/
│ ├── PluginBackendClient.cpp
│ ├── PluginBackendClient.h
│ ├── PluginConfig.h
│ ├── PluginEditor.cpp
│ ├── PluginEditor.h
│ ├── PluginEditorPreview.cpp
│ ├── PluginEditorState.cpp
│ ├── PluginEnums.cpp
│ ├── PluginEnums.h
│ ├── PluginMockGeneration.cpp
│ ├── PluginMockGeneration.h
│ ├── PluginPreview.cpp
│ ├── PluginPreview.h
│ ├── PluginProcessor.cpp
│ ├── PluginProcessor.h
│ ├── PluginState.cpp
│ └── PluginState.h
├── profile_inference.py
├── proxy_config.txt.example
├── pyproject.toml
├── quick_test.bat
├── quick_test.sh
├── requirements-rocm-linux.txt
├── requirements-rocm.txt
├── requirements-sidestep.txt
├── requirements-xpu.txt
├── requirements.txt
├── run_api_server.sh
├── run_openrouter_api_server.sh
├── scripts/
│ ├── check_gpu.py
│ ├── fetch-awesome.mjs
│ ├── lora_data_prepare/
│ │ ├── elevenlabs_transcription.py
│ │ ├── gemini_caption.py
│ │ └── whisper_transcription.py
│ ├── new_pr_branch.ps1
│ ├── prepare_vae_calibration_data.py
│ └── profile_vram.py
├── setup_xpu.bat
├── start_api_server.bat
├── start_api_server.sh
├── start_api_server_macos.sh
├── start_api_server_rocm.bat
├── start_api_server_rocm.sh
├── start_api_server_xpu.bat
├── start_gradio_ui.bat
├── start_gradio_ui.sh
├── start_gradio_ui_macos.sh
├── start_gradio_ui_macos_manual.sh
├── start_gradio_ui_manual.bat
├── start_gradio_ui_manual.sh
├── start_gradio_ui_rocm.bat
├── start_gradio_ui_rocm.sh
├── start_gradio_ui_rocm_manual.bat
├── start_gradio_ui_rocm_manual.sh
├── start_gradio_ui_xpu.bat
├── start_gradio_ui_xpu_manual.bat
├── test_env_detection.bat
├── test_env_detection.sh
├── test_git_update.bat
├── test_git_update.sh
├── train.py
└── ui/
├── studio.html
└── studio_html_test.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .claude/skills/acestep/SKILL.md
================================================
---
name: acestep
description: Use ACE-Step API to generate music, edit songs, and remix music. Supports text-to-music, lyrics generation, audio continuation, and audio repainting. Use this skill when users mention generating music, creating songs, music production, remix, or audio continuation.
allowed-tools: Read, Write, Bash, Skill
---
# ACE-Step Music Generation Skill
Use ACE-Step V1.5 API for music generation. **Always use `scripts/acestep.sh` script** — do NOT call API endpoints directly.
## Quick Start
```bash
# 1. cd to this skill's directory
cd {project_root}/{.claude or .codex}/skills/acestep/
# 2. Check API service health
./scripts/acestep.sh health
# 3. Generate with lyrics (recommended)
./scripts/acestep.sh generate -c "pop, female vocal, piano" -l "[Verse] Your lyrics here..." --duration 120 --language zh
# 4. Output saved to: {project_root}/acestep_output/
```
## Workflow
For user requests requiring vocals:
1. Use the **acestep-songwriting** skill for lyrics writing, caption creation, duration/BPM/key selection
2. Write complete, well-structured lyrics yourself based on the songwriting guide
3. Generate using Caption mode with `-c` and `-l` parameters
Only use Simple/Random mode (`-d` or `random`) for quick inspiration or instrumental exploration.
If the user needs a simple music video, use the **acestep-simplemv** skill to render one with waveform visualization and synced lyrics.
**MV Production Requirements**: Making a simple MV requires three additional skills to be installed:
- **acestep-songwriting** — for writing lyrics and planning song structure
- **acestep-lyrics-transcription** — for transcribing audio to timestamped lyrics (LRC)
- **acestep-simplemv** — for rendering the final music video
- **acestep-thumbnail** (optional) — for generating cover art / MV background images via Gemini API
**MV Background Image**: When the user requests MV production, ask whether they want a background image for the video:
1. **Generate via Gemini** — use the **acestep-thumbnail** skill (requires Gemini API key configuration)
2. **Provide an existing image** — user supplies a local image path
3. **Skip** — use the default animated gradient background (no image needed)
Use `AskUserQuestion` to let the user choose before proceeding with MV rendering.
**Parallel Processing**: Lyrics transcription and thumbnail generation are independent tasks. When the user chooses to generate a background image, run **acestep-lyrics-transcription** and **acestep-thumbnail** in parallel (e.g. via two concurrent Agent calls) to save time, then use both outputs for the final MV render.
## Script Commands
**CRITICAL - Complete Lyrics Input**: When providing lyrics via the `-l` parameter, you MUST pass ALL lyrics content WITHOUT any omission:
- If user provides lyrics, pass the ENTIRE text they give you
- If you generate lyrics yourself, pass the COMPLETE lyrics you created
- NEVER truncate, shorten, or pass only partial lyrics
- Missing lyrics will result in incomplete or incoherent songs
**Music Parameters**: Use the **acestep-songwriting** skill for guidance on duration, BPM, key scale, and time signature.
```bash
# need to cd to this skill's directory first
cd {project_root}/{.claude or .codex}/skills/acestep/
# Caption mode - RECOMMENDED: Write lyrics first, then generate
./scripts/acestep.sh generate -c "Electronic pop, energetic synths" -l "[Verse] Your complete lyrics
[Chorus] Full chorus here..." --duration 120 --bpm 128
# Instrumental only
./scripts/acestep.sh generate "Jazz with saxophone"
# Quick exploration (Simple/Random mode)
./scripts/acestep.sh generate -d "A cheerful song about spring"
./scripts/acestep.sh random
# Cover / Repainting from source audio
./scripts/acestep.sh cover song.mp3 -c "Rock cover style" -l "[Verse] Lyrics..." --duration 120 --bpm 128
./scripts/acestep.sh generate --src-audio song.mp3 --task-type repaint -c "Pop" --repaint-start 30 --repaint-end 60
# Music attribute options
./scripts/acestep.sh generate "Rock" --duration 60 --bpm 120 --key-scale "C major" --time-sig "4/4"
./scripts/acestep.sh generate "Rock" --duration 60 --batch 2
./scripts/acestep.sh generate "EDM" --no-thinking # Faster
# Other commands
./scripts/acestep.sh status <job_id>
./scripts/acestep.sh health
./scripts/acestep.sh models
```
### Cover / Audio Repainting
The `cover` command generates music based on a source audio file. The audio is base64-encoded and sent to the API.
```bash
# Cover: regenerate with new style/lyrics, preserving melody structure
./scripts/acestep.sh cover input.mp3 -c "Jazz cover" -l "[Verse] New lyrics..." --duration 120
# Repainting: modify a specific region of the audio
./scripts/acestep.sh generate --src-audio input.mp3 --task-type repaint -c "Pop ballad" --repaint-start 30 --repaint-end 90
# Cover options
# --src-audio Source audio file path
# --task-type cover (default with --src-audio), repaint, text2music
# --cover-strength 0.0-1.0 (default: 1.0, higher = closer to source)
# --repaint-start Repainting start position (seconds)
# --repaint-end Repainting end position (seconds)
# --key-scale Musical key (e.g. "E minor")
# --time-signature Time signature (e.g. "4/4")
```
**Note**: For cloud API usage, large audio files may be rejected by Cloudflare. Compress audio before uploading if needed (e.g. using ffmpeg: `ffmpeg -i input.mp3 -b:a 64k -ar 24000 -ac 1 compressed.mp3`).
## Output Files
After generation, the script automatically saves results to the `acestep_output` folder in the project root (same level as `.claude`):
```
project_root/
├── .claude/
│ └── skills/acestep/...
├── acestep_output/ # Output directory
│ ├── <job_id>.json # Complete task result (JSON)
│ ├── <job_id>_1.mp3 # First audio file
│ ├── <job_id>_2.mp3 # Second audio file (if batch_size > 1)
│ └── ...
└── ...
```
### JSON Result Structure
**Important**: When LM enhancement is enabled (`use_format=true`), the final synthesized content may differ from your input. Check the JSON file for actual values:
| Field | Description |
|-------|-------------|
| `prompt` | **Actual caption** used for synthesis (may be LM-enhanced) |
| `lyrics` | **Actual lyrics** used for synthesis (may be LM-enhanced) |
| `metas.prompt` | Original input caption |
| `metas.lyrics` | Original input lyrics |
| `metas.bpm` | BPM used |
| `metas.keyscale` | Key scale used |
| `metas.duration` | Duration in seconds |
| `generation_info` | Detailed timing and model info |
| `seed_value` | Seeds used (for reproducibility) |
| `lm_model` | LM model name |
| `dit_model` | DiT model name |
To get the actual synthesized lyrics, parse the JSON and read the top-level `lyrics` field, not `metas.lyrics`.
## Configuration
**Important**: Configuration follows this priority (high to low):
1. **Command line arguments** > **config.json defaults**
2. User-specified parameters **temporarily override** defaults but **do not modify** config.json
3. Only `config --set` command **permanently modifies** config.json
### Default Config File (`scripts/config.json`)
```json
{
"api_url": "http://127.0.0.1:8001",
"api_key": "",
"api_mode": "completion",
"generation": {
"thinking": true,
"use_format": false,
"use_cot_caption": true,
"use_cot_language": false,
"batch_size": 1,
"audio_format": "mp3",
"vocal_language": "en"
}
}
```
| Option | Default | Description |
|--------|---------|-------------|
| `api_url` | `http://127.0.0.1:8001` | API server address |
| `api_key` | `""` | API authentication key (optional) |
| `api_mode` | `completion` | API mode: `completion` (OpenRouter, default) or `native` (polling) |
| `generation.thinking` | `true` | Enable 5Hz LM (higher quality, slower) |
| `generation.audio_format` | `mp3` | Output format (mp3/wav/flac) |
| `generation.vocal_language` | `en` | Vocal language |
## Prerequisites - ACE-Step API Service
**IMPORTANT**: This skill requires the ACE-Step API server to be running.
### Required Dependencies
The `scripts/acestep.sh` script requires: **curl** and **jq**.
```bash
# Check dependencies
curl --version
jq --version
```
If jq is not installed, the script will attempt to install it automatically. If automatic installation fails:
- **Windows**: `choco install jq` or download from https://jqlang.github.io/jq/download/
- **macOS**: `brew install jq`
- **Linux**: `sudo apt-get install jq` (Debian/Ubuntu) or `sudo dnf install jq` (Fedora)
### Before First Use
**You MUST check the API key and URL status before proceeding.** Run:
```bash
cd "{project_root}/{.claude or .codex}/skills/acestep/" && bash ./scripts/acestep.sh config --check-key
cd "{project_root}/{.claude or .codex}/skills/acestep/" && bash ./scripts/acestep.sh config --get api_url
```
#### Case 1: Using Official Cloud API (`https://api.acemusic.ai`) without API key
If `api_url` is `https://api.acemusic.ai` and `api_key` is `empty`, you MUST stop and guide the user to configure their key:
1. Tell the user: "You're using the ACE-Step official cloud API, but no API key is configured. An API key is required to use this service."
2. Explain how to get a key: API keys are currently available through [acemusic.ai](https://acemusic.ai/api-key) for free.
3. Use `AskUserQuestion` to ask the user to provide their API key.
4. Once provided, configure it:
```bash
cd "{project_root}/{.claude or .codex}/skills/acestep/" && bash ./scripts/acestep.sh config --set api_key <KEY>
```
5. Additionally, inform the user: "If you also want to render music videos (MV), it's recommended to configure a lyrics transcription API key as well (OpenAI Whisper or ElevenLabs Scribe), so that lyrics can be automatically transcribed with accurate timestamps. You can configure it later via the `acestep-lyrics-transcription` skill."
#### Case 2: API key is configured
Verify the API endpoint: `./scripts/acestep.sh health` and proceed with music generation.
#### Case 3: Using local/custom API without key
Local services (`http://127.0.0.1:*`) typically don't require a key. Verify with `./scripts/acestep.sh health` and proceed.
If health check fails:
- Ask: "Do you have ACE-Step installed?"
- **If installed but not running**: Use the acestep-docs skill to help them start the service
- **If not installed**: Use acestep-docs skill to guide through installation
### Service Configuration
**Official Cloud API:** ACE-Step provides an official API endpoint at `https://api.acemusic.ai`. To use it:
```bash
./scripts/acestep.sh config --set api_url "https://api.acemusic.ai"
./scripts/acestep.sh config --set api_key "your-key"
./scripts/acestep.sh config --set api_mode completion
```
API keys are currently available through [acemusic.ai](https://acemusic.ai/api-key) for free.
**Local Service (Default):** No configuration needed — connects to `http://127.0.0.1:8001`.
**Custom Remote Service:** Update `scripts/config.json` or use:
```bash
./scripts/acestep.sh config --set api_url "http://remote-server:8001"
./scripts/acestep.sh config --set api_key "your-key"
```
**API Key Handling**: When checking whether an API key is configured, use `config --check-key` which only reports `configured` or `empty` without printing the actual key. **NEVER use `config --get api_key`** or read `config.json` directly — these would expose the user's API key. The `config --list` command is safe — it automatically masks API keys as `***` in output.
### API Mode
The skill supports two API modes. Switch via `api_mode` in `scripts/config.json`:
| Mode | Endpoint | Description |
|------|----------|-------------|
| `completion` (default) | `/v1/chat/completions` | OpenRouter-compatible, sync request, audio returned as base64 |
| `native` | `/release_task` + `/query_result` | Async polling mode, supports all parameters |
**Switch mode:**
```bash
./scripts/acestep.sh config --set api_mode completion
./scripts/acestep.sh config --set api_mode native
```
**Completion mode notes:**
- No polling needed — single request returns result directly
- Audio is base64-encoded inline in the response (auto-decoded and saved)
- `inference_steps`, `infer_method`, `shift` are not configurable (server defaults)
- `--no-wait` and `status` commands are not applicable in completion mode
- Requires `model` field — auto-detected from `/v1/models` if not specified
### Using acestep-docs Skill for Setup Help
**IMPORTANT**: For installation and startup, always use the acestep-docs skill to get complete and accurate guidance.
**DO NOT provide simplified startup commands** - each user's environment may be different. Always guide them to use acestep-docs for proper setup.
---
For API debugging, see [API Reference](./api-reference.md).
================================================
FILE: .claude/skills/acestep/api-reference.md
================================================
# ACE-Step API Reference
> For debugging and advanced usage only. Normal operations should use `scripts/acestep.sh`.
## Native Mode Endpoints
All responses wrapped: `{"data": <payload>, "code": 200, "error": null, "timestamp": ...}`
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/health` | GET | Health check |
| `/release_task` | POST | Create generation task |
| `/query_result` | POST | Query task status, body: `{"task_id_list": ["id"]}` |
| `/v1/models` | GET | List available models |
| `/v1/audio?path={path}` | GET | Download audio file |
## Completion Mode Endpoints
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/v1/chat/completions` | POST | Generate music (OpenRouter-compatible) |
| `/v1/models` | GET | List available models (OpenRouter format) |
## Query Result Response
```json
{
"data": [{
"task_id": "xxx",
"status": 1,
"result": "[{\"file\":\"/v1/audio?path=...\",\"metas\":{\"bpm\":120,\"duration\":60,\"keyscale\":\"C Major\"}}]"
}]
}
```
Status codes: `0` = processing, `1` = success, `2` = failed
## Completion Mode Request (`/v1/chat/completions`)
**Caption mode** — prompt and lyrics wrapped in XML tags inside message content:
```json
{
"model": "acestep/ACE-Step-v1.5",
"messages": [{"role": "user", "content": "<prompt>Jazz with saxophone</prompt><lyrics>[Verse] Hello...</lyrics>"}],
"stream": false,
"thinking": true,
"use_format": false,
"audio_config": {"duration": 90, "bpm": 110, "format": "mp3", "vocal_language": "en"}
}
```
**Simple mode** — plain text message, set `sample_mode: true`:
```json
{
"model": "acestep/ACE-Step-v1.5",
"messages": [{"role": "user", "content": "A cheerful pop song about spring"}],
"stream": false,
"sample_mode": true,
"thinking": true
}
```
## Completion Mode Response
```json
{
"id": "chatcmpl-abc123",
"choices": [{
"message": {
"role": "assistant",
"content": "## Metadata\n**Caption:** ...\n**BPM:** 128\n\n## Lyrics\n...",
"audio": [{"type": "audio_url", "audio_url": {"url": "data:audio/mpeg;base64,..."}}]
},
"finish_reason": "stop"
}]
}
```
Audio is base64-encoded inline — the script auto-decodes and saves to `acestep_output/`.
## Request Parameters (`/release_task`)
Parameters can be placed in `param_obj` object.
### Generation Modes
| Mode | Usage | When to Use |
|------|-------|-------------|
| **Caption** (Recommended) | `generate -c "style" -l "lyrics"` | For vocal songs - write lyrics yourself first |
| **Simple** | `generate -d "description"` | Quick exploration, LM generates everything |
| **Random** | `random` | Random generation for inspiration |
### Core Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `prompt` | string | "" | Music style description (Caption mode) |
| `lyrics` | string | "" | **Full lyrics content** - Pass ALL lyrics without omission. Use `[inst]` for instrumental. Partial/truncated lyrics = incomplete songs |
| `sample_mode` | bool | false | Enable Simple/Random mode |
| `sample_query` | string | "" | Description for Simple mode |
| `thinking` | bool | false | Enable 5Hz LM for audio code generation |
| `use_format` | bool | false | Use LM to enhance caption/lyrics |
| `model` | string | - | DiT model name |
| `batch_size` | int | 1 | Number of audio files to generate |
### Music Attributes
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `audio_duration` | float | - | Duration in seconds |
| `bpm` | int | - | Tempo (beats per minute) |
| `key_scale` | string | "" | Key (e.g. "C Major") |
| `time_signature` | string | "" | Time signature (e.g. "4/4") |
| `vocal_language` | string | "en" | Language code (en, zh, ja, etc.) |
| `audio_format` | string | "mp3" | Output format (mp3/wav/flac) |
### Generation Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `inference_steps` | int | 8 | Diffusion steps |
| `guidance_scale` | float | 7.0 | CFG scale |
| `seed` | int | -1 | Random seed (-1 for random) |
| `infer_method` | string | "ode" | Diffusion method (ode/sde) |
### Audio Task Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `task_type` | string | "text2music" | text2music / continuation / repainting |
| `src_audio_path` | string | - | Source audio for continuation |
| `repainting_start` | float | 0.0 | Repainting start position (seconds) |
| `repainting_end` | float | - | Repainting end position (seconds) |
### Example Request (Simple Mode)
```json
{
"sample_mode": true,
"sample_query": "A cheerful pop song about spring",
"thinking": true,
"param_obj": {
"duration": 60,
"bpm": 120,
"language": "en"
},
"batch_size": 2
}
```
================================================
FILE: .claude/skills/acestep/scripts/acestep.sh
================================================
#!/bin/bash
#
# ACE-Step Music Generation CLI (Bash + Curl + jq)
#
# Requirements: curl, jq
#
# Usage:
# ./acestep.sh generate "Music description" [options]
# ./acestep.sh random [--no-thinking]
# ./acestep.sh status <job_id>
# ./acestep.sh models
# ./acestep.sh health
# ./acestep.sh config [--get|--set|--reset]
#
# Output:
# - Results saved to output/<job_id>.json
# - Audio files downloaded to output/<job_id>_1.mp3, output/<job_id>_2.mp3, ...
set -e
# Ensure UTF-8 encoding for non-ASCII characters (Japanese, Chinese, etc.)
export LANG="${LANG:-en_US.UTF-8}"
export LC_ALL="${LC_ALL:-en_US.UTF-8}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="${SCRIPT_DIR}/config.json"
# Output dir at same level as .claude (go up 4 levels from scripts/)
OUTPUT_DIR="$(cd "${SCRIPT_DIR}/../../../.." && pwd)/acestep_output"
DEFAULT_API_URL="http://127.0.0.1:8001"
STAR_MARKER_FILE="${SCRIPT_DIR}/.first_gen_done"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
BOLD='\033[1m'
# Show GitHub star prompt on first successful generation
show_star_prompt() {
if [ ! -f "$STAR_MARKER_FILE" ]; then
touch "$STAR_MARKER_FILE"
echo ""
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BOLD} ACE-Step is free and open-source.${NC}"
echo -e " If you enjoyed this, a ${YELLOW}★ Star${NC} on GitHub means a lot to us!"
echo -e " ${CYAN}→ https://github.com/ace-step/ACE-Step-1.5${NC}"
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
fi
}
# Check dependencies
check_deps() {
if ! command -v curl &> /dev/null; then
echo -e "${RED}Error: curl is required but not installed.${NC}"
exit 1
fi
if ! command -v jq &> /dev/null; then
echo -e "${RED}Error: jq is required but not installed.${NC}"
echo "Install: apt install jq / brew install jq / choco install jq"
exit 1
fi
}
# JSON value extractor using jq
# Usage: json_get "$json" ".key" or json_get "$json" ".nested.key"
json_get() {
local json="$1"
local path="$2"
echo "$json" | jq -r "$path // empty" 2>/dev/null
}
# Extract array values using jq
json_get_array() {
local json="$1"
local path="$2"
echo "$json" | jq -r "$path[]? // empty" 2>/dev/null
}
# Ensure output directory exists
ensure_output_dir() {
mkdir -p "$OUTPUT_DIR"
}
# Default config
DEFAULT_CONFIG='{
"api_url": "http://127.0.0.1:8001",
"api_key": "",
"api_mode": "native",
"generation": {
"thinking": true,
"use_format": true,
"use_cot_caption": true,
"use_cot_language": true,
"audio_format": "mp3",
"vocal_language": "en"
}
}'
# Ensure config file exists
ensure_config() {
if [ ! -f "$CONFIG_FILE" ]; then
local example="${SCRIPT_DIR}/config.example.json"
if [ -f "$example" ]; then
cp "$example" "$CONFIG_FILE"
echo -e "${YELLOW}Config file created from config.example.json. Please configure your settings:${NC}"
echo -e " ${CYAN}./scripts/acestep.sh config --set api_url <url>${NC}"
echo -e " ${CYAN}./scripts/acestep.sh config --set api_key <key>${NC}"
else
echo "$DEFAULT_CONFIG" > "$CONFIG_FILE"
fi
fi
}
# Get config value using jq
get_config() {
local key="$1"
ensure_config
# Convert dot notation to jq path: "generation.thinking" -> ".generation.thinking"
local jq_path=".${key}"
local value
# Don't use // operator as it treats boolean false as falsy
value=$(jq -r "$jq_path" "$CONFIG_FILE" 2>/dev/null)
# Remove any trailing whitespace/newlines (Windows compatibility)
# Return empty string if value is "null" (key doesn't exist)
if [ "$value" = "null" ]; then
echo ""
else
echo "$value" | tr -d '\r\n'
fi
}
# Normalize boolean value for jq --argjson
normalize_bool() {
local val="$1"
local default="${2:-false}"
case "$val" in
true|True|TRUE|1) echo "true" ;;
false|False|FALSE|0) echo "false" ;;
*) echo "$default" ;;
esac
}
# Set config value using jq
set_config() {
local key="$1"
local value="$2"
ensure_config
local tmp_file="${CONFIG_FILE}.tmp"
local jq_path=".${key}"
# Determine value type and set accordingly
if [ "$value" = "true" ] || [ "$value" = "false" ]; then
jq "$jq_path = $value" "$CONFIG_FILE" > "$tmp_file"
elif [[ "$value" =~ ^-?[0-9]+$ ]] || [[ "$value" =~ ^-?[0-9]+\.[0-9]+$ ]]; then
jq "$jq_path = $value" "$CONFIG_FILE" > "$tmp_file"
else
jq "$jq_path = \"$value\"" "$CONFIG_FILE" > "$tmp_file"
fi
mv "$tmp_file" "$CONFIG_FILE"
echo "Set $key = $value"
}
# Load API URL
load_api_url() {
local url=$(get_config "api_url")
echo "${url:-$DEFAULT_API_URL}"
}
# Load API Key
load_api_key() {
local key=$(get_config "api_key")
echo "${key:-}"
}
# Check API health
check_health() {
local url="$1"
local status
status=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "${url}/health" 2>/dev/null) || true
[ "$status" = "200" ]
}
# Build auth header
build_auth_header() {
local api_key=$(load_api_key)
if [ -n "$api_key" ]; then
echo "-H \"Authorization: Bearer ${api_key}\""
fi
}
# Prompt for URL
prompt_for_url() {
echo ""
echo -e "${YELLOW}API server is not responding.${NC}"
echo "Please enter the API URL (or press Enter for default):"
read -p "API URL [$DEFAULT_API_URL]: " user_input
echo "${user_input:-$DEFAULT_API_URL}"
}
# Ensure API connection
ensure_connection() {
ensure_config
local api_url=$(load_api_url)
if check_health "$api_url"; then
echo "$api_url"
return 0
fi
echo -e "${YELLOW}Cannot connect to: $api_url${NC}" >&2
local new_url=$(prompt_for_url)
if check_health "$new_url"; then
set_config "api_url" "$new_url" > /dev/null
echo -e "${GREEN}Saved API URL: $new_url${NC}" >&2
echo "$new_url"
return 0
fi
echo -e "${RED}Error: Cannot connect to $new_url${NC}" >&2
exit 1
}
# Save result to JSON file
save_result() {
local job_id="$1"
local result_json="$2"
ensure_output_dir
local output_file="${OUTPUT_DIR}/${job_id}.json"
echo "$result_json" > "$output_file"
echo -e "${GREEN}Result saved: $output_file${NC}"
}
# Health command
cmd_health() {
check_deps
ensure_config
local api_url=$(load_api_url)
echo "Checking API at: $api_url"
if check_health "$api_url"; then
echo -e "${GREEN}Status: OK${NC}"
curl -s "${api_url}/health"
echo ""
else
echo -e "${RED}Status: FAILED${NC}"
exit 1
fi
}
# Config command
cmd_config() {
check_deps
ensure_config
local action=""
local key=""
local value=""
while [[ $# -gt 0 ]]; do
case $1 in
--get) action="get"; key="$2"; shift 2 ;;
--set) action="set"; key="$2"; value="$3"; shift 3 ;;
--reset) action="reset"; shift ;;
--list) action="list"; shift ;;
--check-key) action="check-key"; shift ;;
*) shift ;;
esac
done
case "$action" in
"check-key")
local api_key=$(get_config "api_key")
if [ -n "$api_key" ]; then
echo "api_key: configured"
else
echo "api_key: empty"
fi
;;
"get")
[ -z "$key" ] && { echo -e "${RED}Error: --get requires KEY${NC}"; exit 1; }
local result=$(get_config "$key")
[ -n "$result" ] && echo "$key = $result" || echo "Key not found: $key"
;;
"set")
[ -z "$key" ] || [ -z "$value" ] && { echo -e "${RED}Error: --set requires KEY VALUE${NC}"; exit 1; }
set_config "$key" "$value"
;;
"reset")
echo "$DEFAULT_CONFIG" > "$CONFIG_FILE"
echo -e "${GREEN}Configuration reset to defaults.${NC}"
jq 'walk(if type == "object" and has("api_key") and (.api_key | length) > 0 then .api_key = "***" else . end)' "$CONFIG_FILE"
;;
"list")
echo "Current configuration:"
jq 'walk(if type == "object" and has("api_key") and (.api_key | length) > 0 then .api_key = "***" else . end)' "$CONFIG_FILE"
;;
*)
echo "Config file: $CONFIG_FILE"
echo "Output dir: $OUTPUT_DIR"
echo "----------------------------------------"
cat "$CONFIG_FILE"
echo "----------------------------------------"
echo ""
echo "Usage:"
echo " config --list Show config"
echo " config --get <key> Get value"
echo " config --set <key> <val> Set value"
echo " config --reset Reset to defaults"
;;
esac
}
# Models command
cmd_models() {
check_deps
local api_url=$(ensure_connection)
local api_key=$(load_api_key)
echo "Available Models:"
echo "----------------------------------------"
if [ -n "$api_key" ]; then
curl -s -H "Authorization: Bearer ${api_key}" "${api_url}/v1/models"
else
curl -s "${api_url}/v1/models"
fi
echo ""
}
# Query job result via /query_result endpoint
query_job_result() {
local api_url="$1"
local job_id="$2"
local api_key=$(load_api_key)
local payload=$(jq -n --arg id "$job_id" '{"task_id_list": [$id]}')
if [ -n "$api_key" ]; then
curl -s -X POST "${api_url}/query_result" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer ${api_key}" \
-d "$payload"
else
curl -s -X POST "${api_url}/query_result" \
-H "Content-Type: application/json; charset=utf-8" \
-d "$payload"
fi
}
# Parse query_result response to extract status (0=processing, 1=success, 2=failed)
# Response is wrapped: {"data": [...], "code": 200, ...}
# Uses temp file to avoid jq pipe issues with special characters on Windows
parse_query_status() {
local response="$1"
local tmp_file=$(mktemp)
printf '%s' "$response" > "$tmp_file"
jq -r '.data[0].status // .[0].status // 0' "$tmp_file"
rm -f "$tmp_file"
}
# Parse result JSON string from query_result response
# The result field is a JSON string that needs to be parsed
# Uses temp file to avoid jq pipe issues with special characters on Windows
parse_query_result() {
local response="$1"
local tmp_file=$(mktemp)
printf '%s' "$response" > "$tmp_file"
jq -r '.data[0].result // .[0].result // "[]"' "$tmp_file"
rm -f "$tmp_file"
}
# Extract audio file paths from result (returns newline-separated paths)
# Uses temp file to avoid jq pipe issues with special characters on Windows
parse_audio_files() {
local result="$1"
local tmp_file=$(mktemp)
printf '%s' "$result" > "$tmp_file"
jq -r '.[].file // empty' "$tmp_file" 2>/dev/null
rm -f "$tmp_file"
}
# Extract metas value from result
# Uses temp file to avoid jq pipe issues with special characters on Windows
parse_metas_value() {
local result="$1"
local key="$2"
local tmp_file=$(mktemp)
printf '%s' "$result" > "$tmp_file"
jq -r ".[0].metas.$key // .[0].$key // empty" "$tmp_file" 2>/dev/null
rm -f "$tmp_file"
}
# Status command
cmd_status() {
check_deps
local job_id="$1"
[ -z "$job_id" ] && { echo -e "${RED}Error: job_id required${NC}"; echo "Usage: $0 status <job_id>"; exit 1; }
local api_url=$(ensure_connection)
local response=$(query_job_result "$api_url" "$job_id")
local status=$(parse_query_status "$response")
echo "Job ID: $job_id"
case "$status" in
0)
echo "Status: processing"
;;
1)
echo "Status: succeeded"
echo ""
local result_file=$(mktemp)
parse_query_result "$response" > "$result_file"
local bpm=$(jq -r '.[0].metas.bpm // .[0].bpm // empty' "$result_file" 2>/dev/null)
local keyscale=$(jq -r '.[0].metas.keyscale // .[0].keyscale // empty' "$result_file" 2>/dev/null)
local duration=$(jq -r '.[0].metas.duration // .[0].duration // empty' "$result_file" 2>/dev/null)
echo "Result:"
[ -n "$bpm" ] && echo " BPM: $bpm"
[ -n "$keyscale" ] && echo " Key: $keyscale"
[ -n "$duration" ] && echo " Duration: ${duration}s"
# Save and download
save_result "$job_id" "$response"
download_audios "$api_url" "$job_id" "$result_file"
rm -f "$result_file"
;;
2)
echo "Status: failed"
echo ""
echo -e "${RED}Task failed${NC}"
;;
*)
echo "Status: unknown ($status)"
;;
esac
}
# Download audio files from result file
# Usage: download_audios <api_url> <job_id> <result_file>
download_audios() {
local api_url="$1"
local job_id="$2"
local result_file="$3"
local api_key=$(load_api_key)
ensure_output_dir
local audio_format=$(get_config "generation.audio_format")
[ -z "$audio_format" ] && audio_format="mp3"
# Read result file content and extract audio paths using pipe (avoid temp file path issues on Windows)
local result_content
result_content=$(cat "$result_file" 2>/dev/null)
if [ -z "$result_content" ]; then
echo -e " ${RED}Error: Result file is empty or cannot be read${NC}"
return 1
fi
# Extract audio paths using pipe instead of file (better Windows compatibility)
local audio_paths
audio_paths=$(echo "$result_content" | jq -r '.[].file // empty' 2>&1)
local jq_exit_code=$?
if [ $jq_exit_code -ne 0 ]; then
echo -e " ${RED}Error: Failed to parse result JSON${NC}"
echo -e " ${RED}jq error: $audio_paths${NC}"
return 1
fi
if [ -z "$audio_paths" ]; then
echo -e " ${YELLOW}No audio files found in result${NC}"
return 0
fi
local count=1
while IFS= read -r audio_path; do
# Skip empty lines and remove potential Windows carriage return
audio_path=$(echo "$audio_path" | tr -d '\r')
if [ -n "$audio_path" ]; then
local output_file="${OUTPUT_DIR}/${job_id}_${count}.${audio_format}"
local download_url="${api_url}${audio_path}"
echo -e " ${CYAN}Downloading audio $count...${NC}"
local curl_output
local curl_exit_code
if [ -n "$api_key" ]; then
curl_output=$(curl -s --connect-timeout 10 --max-time 300 \
-w "%{http_code}" \
-o "$output_file" \
-H "Authorization: Bearer ${api_key}" \
"$download_url" 2>&1)
curl_exit_code=$?
else
curl_output=$(curl -s --connect-timeout 10 --max-time 300 \
-w "%{http_code}" \
-o "$output_file" \
"$download_url" 2>&1)
curl_exit_code=$?
fi
if [ $curl_exit_code -ne 0 ]; then
echo -e " ${RED}Failed to download (curl error $curl_exit_code): $download_url${NC}"
rm -f "$output_file" 2>/dev/null
elif [ -f "$output_file" ] && [ -s "$output_file" ]; then
echo -e " ${GREEN}Saved: $output_file${NC}"
else
echo -e " ${RED}Failed to download (HTTP $curl_output): $download_url${NC}"
rm -f "$output_file" 2>/dev/null
fi
count=$((count + 1))
fi
done <<< "$audio_paths"
}
# =============================================================================
# Completion Mode (OpenRouter /v1/chat/completions)
# =============================================================================
# Load api_mode from config (default: native)
load_api_mode() {
local mode=$(get_config "api_mode")
echo "${mode:-native}"
}
# Get model ID from /v1/models endpoint for completion mode
get_completion_model() {
local api_url="$1"
local user_model="$2"
local api_key=$(load_api_key)
# If user specified a model, prefix with acemusic/ if needed
if [ -n "$user_model" ]; then
if [[ "$user_model" == */* ]]; then
echo "$user_model"
else
echo "acemusic/${user_model}"
fi
return
fi
# Query /v1/models for the first available model
local response
if [ -n "$api_key" ]; then
response=$(curl -s -H "Authorization: Bearer ${api_key}" "${api_url}/v1/models" 2>/dev/null)
else
response=$(curl -s "${api_url}/v1/models" 2>/dev/null)
fi
local model_id
model_id=$(echo "$response" | jq -r '.data[0].id // empty' 2>/dev/null)
echo "${model_id:-acemusic/acestep-v15-turbo}"
}
# Decode base64 audio data URL and save to file
# Handles cross-platform compatibility (Linux/macOS/Windows MSYS)
decode_base64_audio() {
local data_url="$1"
local output_file="$2"
# Strip data URL prefix: data:audio/mpeg;base64,...
local b64_data="${data_url#data:*;base64,}"
local tmp_b64=$(mktemp)
printf '%s' "$b64_data" > "$tmp_b64"
if command -v base64 &> /dev/null; then
# Linux / macOS / MSYS2
base64 -d < "$tmp_b64" > "$output_file" 2>/dev/null || \
base64 -D < "$tmp_b64" > "$output_file" 2>/dev/null || \
python3 -c "import base64,sys; sys.stdout.buffer.write(base64.b64decode(sys.stdin.read()))" < "$tmp_b64" > "$output_file" 2>/dev/null || \
python -c "import base64,sys; sys.stdout.buffer.write(base64.b64decode(sys.stdin.read()))" < "$tmp_b64" > "$output_file" 2>/dev/null
else
# Fallback to python
python3 -c "import base64,sys; sys.stdout.buffer.write(base64.b64decode(sys.stdin.read()))" < "$tmp_b64" > "$output_file" 2>/dev/null || \
python -c "import base64,sys; sys.stdout.buffer.write(base64.b64decode(sys.stdin.read()))" < "$tmp_b64" > "$output_file" 2>/dev/null
fi
local decode_ok=$?
rm -f "$tmp_b64"
return $decode_ok
}
# Parse completion response: extract metadata, save audio files
# Usage: parse_completion_response <response_file> <job_id>
parse_completion_response() {
local resp_file="$1"
local job_id="$2"
ensure_output_dir
local audio_format=$(get_config "generation.audio_format")
[ -z "$audio_format" ] && audio_format="mp3"
# Check for error
local finish_reason
finish_reason=$(jq -r '.choices[0].finish_reason // "stop"' "$resp_file" 2>/dev/null)
if [ "$finish_reason" = "error" ]; then
local err_content
err_content=$(jq -r '.choices[0].message.content // "Unknown error"' "$resp_file" 2>/dev/null)
echo -e "${RED}Generation failed: $err_content${NC}"
return 1
fi
# Extract and display text content (metadata + lyrics)
local content
content=$(jq -r '.choices[0].message.content // empty' "$resp_file" 2>/dev/null)
if [ -n "$content" ]; then
echo "$content"
echo ""
fi
# Extract and save audio files
local audio_count
audio_count=$(jq -r '.choices[0].message.audio | length // 0' "$resp_file" 2>/dev/null)
if [ "$audio_count" -gt 0 ] 2>/dev/null; then
local i=0
while [ "$i" -lt "$audio_count" ]; do
local audio_url
audio_url=$(jq -r ".choices[0].message.audio[$i].audio_url.url // empty" "$resp_file" 2>/dev/null)
if [ -n "$audio_url" ]; then
local output_file="${OUTPUT_DIR}/${job_id}_$((i+1)).${audio_format}"
echo -e " ${CYAN}Decoding audio $((i+1))...${NC}"
if decode_base64_audio "$audio_url" "$output_file"; then
if [ -f "$output_file" ] && [ -s "$output_file" ]; then
echo -e " ${GREEN}Saved: $output_file${NC}"
else
echo -e " ${RED}Failed to decode audio $((i+1))${NC}"
rm -f "$output_file" 2>/dev/null
fi
else
echo -e " ${RED}Failed to decode audio $((i+1))${NC}"
rm -f "$output_file" 2>/dev/null
fi
fi
i=$((i+1))
done
else
echo -e " ${YELLOW}No audio files in response${NC}"
fi
# Save full response JSON (strip base64 audio to keep file small)
local clean_resp
clean_resp=$(jq 'del(.choices[].message.audio[].audio_url.url)' "$resp_file" 2>/dev/null)
if [ -n "$clean_resp" ]; then
save_result "$job_id" "$clean_resp"
else
save_result "$job_id" "$(cat "$resp_file")"
fi
}
# Send request to /v1/chat/completions and handle response
# Usage: send_completion_request <api_url> <payload_file> <job_id_var>
send_completion_request() {
local api_url="$1"
local payload_file="$2"
local api_key=$(load_api_key)
local resp_file=$(mktemp)
local http_code
if [ -n "$api_key" ]; then
http_code=$(curl -s -w "%{http_code}" --connect-timeout 10 --max-time 660 \
-o "$resp_file" \
-X POST "${api_url}/v1/chat/completions" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer ${api_key}" \
-A "curl/8.7.1" \
--data-binary "@${payload_file}")
else
http_code=$(curl -s -w "%{http_code}" --connect-timeout 10 --max-time 660 \
-o "$resp_file" \
-X POST "${api_url}/v1/chat/completions" \
-H "Content-Type: application/json; charset=utf-8" \
-A "curl/8.7.1" \
--data-binary "@${payload_file}")
fi
rm -f "$payload_file"
if [ "$http_code" != "200" ]; then
local err_detail
err_detail=$(jq -r '.detail // .error.message // empty' "$resp_file" 2>/dev/null)
echo -e "${RED}Error: HTTP $http_code${NC}"
[ -n "$err_detail" ] && echo -e "${RED}$err_detail${NC}"
rm -f "$resp_file"
return 1
fi
# Generate a job_id from the completion id
local job_id
job_id=$(jq -r '.id // empty' "$resp_file" 2>/dev/null)
[ -z "$job_id" ] && job_id="completion-$(date +%s)"
echo ""
echo -e "${GREEN}Generation completed!${NC}"
echo ""
parse_completion_response "$resp_file" "$job_id"
rm -f "$resp_file"
echo ""
echo -e "${GREEN}Done! Files saved to: $OUTPUT_DIR${NC}"
show_star_prompt
}
# Wait for job and download results
wait_for_job() {
local api_url="$1"
local job_id="$2"
echo "Job created: $job_id"
echo "Output: $OUTPUT_DIR"
echo ""
while true; do
local response=$(query_job_result "$api_url" "$job_id")
local status=$(parse_query_status "$response")
case "$status" in
1)
echo ""
echo -e "${GREEN}Generation completed!${NC}"
echo ""
local result_file=$(mktemp)
parse_query_result "$response" > "$result_file"
local bpm=$(jq -r '.[0].metas.bpm // .[0].bpm // empty' "$result_file" 2>/dev/null)
local keyscale=$(jq -r '.[0].metas.keyscale // .[0].keyscale // empty' "$result_file" 2>/dev/null)
local duration=$(jq -r '.[0].metas.duration // .[0].duration // empty' "$result_file" 2>/dev/null)
echo "Metadata:"
[ -n "$bpm" ] && echo " BPM: $bpm"
[ -n "$keyscale" ] && echo " Key: $keyscale"
[ -n "$duration" ] && echo " Duration: ${duration}s"
echo ""
# Save result JSON
save_result "$job_id" "$response"
# Download audio files
echo "Downloading audio files..."
download_audios "$api_url" "$job_id" "$result_file"
rm -f "$result_file"
echo ""
echo -e "${GREEN}Done! Files saved to: $OUTPUT_DIR${NC}"
show_star_prompt
return 0
;;
2)
echo ""
echo -e "${RED}Generation failed!${NC}"
# Save error result
save_result "$job_id" "$response"
return 1
;;
0)
printf "\rProcessing... "
;;
*)
printf "\rWaiting... "
;;
esac
sleep 5
done
}
# Generate command
cmd_generate() {
check_deps
ensure_config
local caption="" lyrics="" description="" thinking="" use_format=""
local no_thinking=false no_format=false no_wait=false
local model="" language="" steps="" guidance="" seed="" duration="" bpm="" batch=""
local task_type="" src_audio="" cover_strength="" repaint_start="" repaint_end=""
local key_scale="" time_signature=""
while [[ $# -gt 0 ]]; do
case $1 in
--caption|-c) caption="$2"; shift 2 ;;
--lyrics|-l) lyrics="$2"; shift 2 ;;
--description|-d) description="$2"; shift 2 ;;
--thinking|-t) thinking="true"; shift ;;
--no-thinking) no_thinking=true; shift ;;
--use-format) use_format="true"; shift ;;
--no-format) no_format=true; shift ;;
--model|-m) model="$2"; shift 2 ;;
--language|--vocal-language) language="$2"; shift 2 ;;
--steps) steps="$2"; shift 2 ;;
--guidance) guidance="$2"; shift 2 ;;
--seed) seed="$2"; shift 2 ;;
--duration) duration="$2"; shift 2 ;;
--bpm) bpm="$2"; shift 2 ;;
--batch) batch="$2"; shift 2 ;;
--no-wait) no_wait=true; shift ;;
--task-type) task_type="$2"; shift 2 ;;
--src-audio) src_audio="$2"; shift 2 ;;
--cover-strength) cover_strength="$2"; shift 2 ;;
--repaint-start) repaint_start="$2"; shift 2 ;;
--repaint-end) repaint_end="$2"; shift 2 ;;
--key-scale|--key) key_scale="$2"; shift 2 ;;
--time-signature|--time-sig) time_signature="$2"; shift 2 ;;
*) [ -z "$caption" ] && caption="$1"; shift ;;
esac
done
# If no caption but has description, use simple mode
if [ -z "$caption" ] && [ -z "$description" ]; then
echo -e "${RED}Error: caption or description required${NC}"
echo "Usage: $0 generate \"Music description\" [options]"
echo " $0 generate -d \"Simple description\" [options]"
exit 1
fi
local api_url=$(ensure_connection)
# Get defaults
local def_thinking=$(get_config "generation.thinking")
local def_format=$(get_config "generation.use_format")
local def_cot_caption=$(get_config "generation.use_cot_caption")
local def_cot_language=$(get_config "generation.use_cot_language")
local def_language=$(get_config "generation.vocal_language")
local def_audio_format=$(get_config "generation.audio_format")
[ -z "$thinking" ] && thinking="${def_thinking:-true}"
[ -z "$use_format" ] && use_format="${def_format:-true}"
[ -z "$language" ] && language="${def_language:-en}"
[ "$no_thinking" = true ] && thinking="false"
[ "$no_format" = true ] && use_format="false"
# Normalize boolean values for jq --argjson
thinking=$(normalize_bool "$thinking" "true")
use_format=$(normalize_bool "$use_format" "true")
local cot_caption=$(normalize_bool "$def_cot_caption" "true")
local cot_language=$(normalize_bool "$def_cot_language" "true")
# Build payload using jq for proper escaping
local payload=$(jq -n \
--arg prompt "$caption" \
--arg lyrics "${lyrics:-}" \
--arg sample_query "${description:-}" \
--argjson thinking "$thinking" \
--argjson use_format "$use_format" \
--argjson use_cot_caption "$cot_caption" \
--argjson use_cot_language "$cot_language" \
--arg vocal_language "$language" \
--arg audio_format "${def_audio_format:-mp3}" \
'{
prompt: $prompt,
lyrics: $lyrics,
sample_query: $sample_query,
thinking: $thinking,
use_format: $use_format,
use_cot_caption: $use_cot_caption,
use_cot_language: $use_cot_language,
vocal_language: $vocal_language,
audio_format: $audio_format,
use_random_seed: true
}')
# Validate src_audio file exists if provided
if [ -n "$src_audio" ]; then
if [ ! -f "$src_audio" ]; then
echo -e "${RED}Error: Source audio file not found: $src_audio${NC}"
exit 1
fi
# Default task_type to "cover" when src_audio is provided
[ -z "$task_type" ] && task_type="cover"
fi
# Add optional parameters
[ -n "$model" ] && payload=$(echo "$payload" | jq --arg v "$model" '. + {model: $v}')
[ -n "$steps" ] && payload=$(echo "$payload" | jq --argjson v "$steps" '. + {inference_steps: $v}')
[ -n "$guidance" ] && payload=$(echo "$payload" | jq --argjson v "$guidance" '. + {guidance_scale: $v}')
[ -n "$seed" ] && payload=$(echo "$payload" | jq --argjson v "$seed" '. + {seed: $v, use_random_seed: false}')
[ -n "$duration" ] && payload=$(echo "$payload" | jq --argjson v "$duration" '. + {audio_duration: $v}')
[ -n "$bpm" ] && payload=$(echo "$payload" | jq --argjson v "$bpm" '. + {bpm: $v}')
[ -n "$batch" ] && payload=$(echo "$payload" | jq --argjson v "$batch" '. + {batch_size: $v}')
[ -n "$task_type" ] && payload=$(echo "$payload" | jq --arg v "$task_type" '. + {task_type: $v}')
[ -n "$src_audio" ] && payload=$(echo "$payload" | jq --arg v "$src_audio" '. + {src_audio_path: $v}')
[ -n "$cover_strength" ] && payload=$(echo "$payload" | jq --argjson v "$cover_strength" '. + {audio_cover_strength: $v}')
[ -n "$repaint_start" ] && payload=$(echo "$payload" | jq --argjson v "$repaint_start" '. + {repainting_start: $v}')
[ -n "$repaint_end" ] && payload=$(echo "$payload" | jq --argjson v "$repaint_end" '. + {repainting_end: $v}')
[ -n "$key_scale" ] && payload=$(echo "$payload" | jq --arg v "$key_scale" '. + {key_scale: $v}')
[ -n "$time_signature" ] && payload=$(echo "$payload" | jq --arg v "$time_signature" '. + {time_signature: $v}')
local api_mode=$(load_api_mode)
echo "Generating music..."
if [ -n "$task_type" ] && [ "$task_type" != "text2music" ]; then
echo " Mode: $(echo "$task_type" | awk '{print toupper(substr($0,1,1)) substr($0,2)}') (${task_type})"
[ -n "$src_audio" ] && echo " Source audio: $src_audio"
elif [ -n "$description" ]; then
echo " Mode: Simple (description)"
echo " Description: ${description:0:50}..."
else
echo " Mode: Caption"
echo " Caption: ${caption:0:50}..."
fi
echo " Thinking: $thinking, Format: $use_format"
echo " API: $api_mode"
echo " Output: $OUTPUT_DIR"
echo ""
if [ "$api_mode" = "completion" ]; then
# --- Completion mode: /v1/chat/completions ---
local model_id=$(get_completion_model "$api_url" "$model")
# Build message content parts
local message_content=""
local sample_mode=false
if [ -n "$description" ]; then
message_content="$description"
sample_mode=true
else
message_content="<prompt>${caption}</prompt>"
[ -n "$lyrics" ] && message_content="${message_content}<lyrics>${lyrics}</lyrics>"
fi
# Build completion payload
local payload_c
if [ -n "$src_audio" ]; then
# Audio input mode: use multipart content array with text + input_audio
# Encode audio to base64 using python to avoid shell argument limits
local audio_b64_file=$(mktemp)
python3 -c "
import base64, sys
with open(sys.argv[1], 'rb') as f:
sys.stdout.write(base64.b64encode(f.read()).decode('ascii'))
" "$src_audio" > "$audio_b64_file"
local audio_ext="${src_audio##*.}"
[ -z "$audio_ext" ] && audio_ext="mp3"
# Build payload with audio using jq --rawfile to read base64 from file
payload_c=$(jq -n \
--arg model "$model_id" \
--arg text_content "$message_content" \
--rawfile audio_b64 "$audio_b64_file" \
--arg audio_format "$audio_ext" \
--argjson thinking "$thinking" \
--argjson use_format "$use_format" \
--argjson sample_mode "$sample_mode" \
--argjson use_cot_caption "$cot_caption" \
--argjson use_cot_language "$cot_language" \
--arg vocal_language "$language" \
--arg format "${def_audio_format:-mp3}" \
--arg task_type "${task_type:-text2music}" \
'{
model: $model,
messages: [{
"role": "user",
"content": [
{"type": "text", "text": $text_content},
{"type": "input_audio", "input_audio": {"data": $audio_b64, "format": $audio_format}}
]
}],
stream: false,
thinking: $thinking,
use_format: $use_format,
sample_mode: $sample_mode,
use_cot_caption: $use_cot_caption,
use_cot_language: $use_cot_language,
task_type: $task_type,
audio_config: {
format: $format,
vocal_language: $vocal_language
}
}')
rm -f "$audio_b64_file"
# Add cover/repainting parameters
[ -n "$cover_strength" ] && payload_c=$(echo "$payload_c" | jq --argjson v "$cover_strength" '. + {audio_cover_strength: $v}')
[ -n "$repaint_start" ] && payload_c=$(echo "$payload_c" | jq --argjson v "$repaint_start" '. + {repainting_start: $v}')
[ -n "$repaint_end" ] && payload_c=$(echo "$payload_c" | jq --argjson v "$repaint_end" '. + {repainting_end: $v}')
else
# Text-only mode: use string content
payload_c=$(jq -n \
--arg model "$model_id" \
--arg content "$message_content" \
--argjson thinking "$thinking" \
--argjson use_format "$use_format" \
--argjson sample_mode "$sample_mode" \
--argjson use_cot_caption "$cot_caption" \
--argjson use_cot_language "$cot_language" \
--arg vocal_language "$language" \
--arg format "${def_audio_format:-mp3}" \
'{
model: $model,
messages: [{"role": "user", "content": $content}],
stream: false,
thinking: $thinking,
use_format: $use_format,
sample_mode: $sample_mode,
use_cot_caption: $use_cot_caption,
use_cot_language: $use_cot_language,
audio_config: {
format: $format,
vocal_language: $vocal_language
}
}')
fi
# Add optional parameters to completion payload
[ -n "$guidance" ] && payload_c=$(echo "$payload_c" | jq --argjson v "$guidance" '. + {guidance_scale: $v}')
[ -n "$seed" ] && payload_c=$(echo "$payload_c" | jq --argjson v "$seed" '. + {seed: $v}')
[ -n "$batch" ] && payload_c=$(echo "$payload_c" | jq --argjson v "$batch" '. + {batch_size: $v}')
[ -n "$duration" ] && payload_c=$(echo "$payload_c" | jq --argjson v "$duration" '.audio_config.duration = $v')
[ -n "$bpm" ] && payload_c=$(echo "$payload_c" | jq --argjson v "$bpm" '.audio_config.bpm = $v')
[ -n "$key_scale" ] && payload_c=$(echo "$payload_c" | jq --arg v "$key_scale" '.audio_config.key_scale = $v')
[ -n "$time_signature" ] && payload_c=$(echo "$payload_c" | jq --arg v "$time_signature" '.audio_config.time_signature = $v')
local temp_payload=$(mktemp)
printf '%s' "$payload_c" > "$temp_payload"
send_completion_request "$api_url" "$temp_payload"
else
# --- Native mode: /release_task + polling ---
local temp_payload=$(mktemp)
printf '%s' "$payload" > "$temp_payload"
local api_key=$(load_api_key)
local response
if [ -n "$api_key" ]; then
response=$(curl -s -X POST "${api_url}/release_task" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer ${api_key}" \
--data-binary "@${temp_payload}")
else
response=$(curl -s -X POST "${api_url}/release_task" \
-H "Content-Type: application/json; charset=utf-8" \
--data-binary "@${temp_payload}")
fi
rm -f "$temp_payload"
local job_id=$(echo "$response" | jq -r '.data.task_id // .task_id // empty')
[ -z "$job_id" ] && { echo -e "${RED}Error: Failed to create job${NC}"; echo "$response"; exit 1; }
if [ "$no_wait" = true ]; then
echo "Job ID: $job_id"
echo "Use '$0 status $job_id' to check progress and download"
else
wait_for_job "$api_url" "$job_id"
fi
fi
}
# Random command
cmd_random() {
check_deps
ensure_config
local thinking="" no_thinking=false no_wait=false
while [[ $# -gt 0 ]]; do
case $1 in
--thinking|-t) thinking="true"; shift ;;
--no-thinking) no_thinking=true; shift ;;
--no-wait) no_wait=true; shift ;;
*) shift ;;
esac
done
local api_url=$(ensure_connection)
local def_thinking=$(get_config "generation.thinking")
[ -z "$thinking" ] && thinking="${def_thinking:-true}"
[ "$no_thinking" = true ] && thinking="false"
# Normalize boolean for jq --argjson
thinking=$(normalize_bool "$thinking" "true")
local api_mode=$(load_api_mode)
echo "Generating random music..."
echo " Thinking: $thinking"
echo " API: $api_mode"
echo " Output: $OUTPUT_DIR"
echo ""
if [ "$api_mode" = "completion" ]; then
# --- Completion mode ---
local model_id=$(get_completion_model "$api_url" "")
local def_audio_format=$(get_config "generation.audio_format")
local payload_c=$(jq -n \
--arg model "$model_id" \
--argjson thinking "$thinking" \
--arg format "${def_audio_format:-mp3}" \
'{
model: $model,
messages: [{"role": "user", "content": "Generate a random song"}],
stream: false,
sample_mode: true,
thinking: $thinking,
audio_config: { format: $format }
}')
local temp_payload=$(mktemp)
printf '%s' "$payload_c" > "$temp_payload"
send_completion_request "$api_url" "$temp_payload"
else
# --- Native mode ---
local payload=$(jq -n --argjson thinking "$thinking" '{sample_mode: true, thinking: $thinking}')
local temp_payload=$(mktemp)
printf '%s' "$payload" > "$temp_payload"
local api_key=$(load_api_key)
local response
if [ -n "$api_key" ]; then
response=$(curl -s -X POST "${api_url}/release_task" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer ${api_key}" \
--data-binary "@${temp_payload}")
else
response=$(curl -s -X POST "${api_url}/release_task" \
-H "Content-Type: application/json; charset=utf-8" \
--data-binary "@${temp_payload}")
fi
rm -f "$temp_payload"
local job_id=$(echo "$response" | jq -r '.data.task_id // .task_id // empty')
[ -z "$job_id" ] && { echo -e "${RED}Error: Failed to create job${NC}"; echo "$response"; exit 1; }
if [ "$no_wait" = true ]; then
echo "Job ID: $job_id"
echo "Use '$0 status $job_id' to check progress and download"
else
wait_for_job "$api_url" "$job_id"
fi
fi
}
# Cover command (shortcut for generate --task-type cover --src-audio)
cmd_cover() {
check_deps
ensure_config
local src_audio=""
local args=()
# Extract src_audio as first positional arg, pass rest to generate
while [[ $# -gt 0 ]]; do
case $1 in
--src-audio) src_audio="$2"; shift 2 ;;
-*) args+=("$1"); shift ;;
*)
if [ -z "$src_audio" ]; then
src_audio="$1"; shift
else
args+=("$1"); shift
fi
;;
esac
done
if [ -z "$src_audio" ]; then
echo -e "${RED}Error: source audio file required${NC}"
echo "Usage: $0 cover <audio_file> -c \"caption\" -l \"lyrics\" [options]"
exit 1
fi
cmd_generate --src-audio "$src_audio" --task-type cover "${args[@]}"
}
# Help
show_help() {
echo "ACE-Step Music Generation CLI"
echo ""
echo "Requirements: curl, jq"
echo ""
echo "Usage: $0 <command> [options]"
echo ""
echo "Commands:"
echo " generate Generate music from text"
echo " cover Cover/repainting from source audio"
echo " random Generate random music"
echo " status Check job status and download results"
echo " models List available models"
echo " health Check API health"
echo " config Manage configuration"
echo ""
echo "Output:"
echo " Results saved to: $OUTPUT_DIR/<job_id>.json"
echo " Audio files: $OUTPUT_DIR/<job_id>_1.mp3, ..."
echo ""
echo "Generate Options:"
echo " -c, --caption Music style/genre description (caption mode)"
echo " -d, --description Simple description, LM auto-generates caption/lyrics"
echo " -l, --lyrics Lyrics text"
echo " -t, --thinking Enable thinking mode (default: true)"
echo " --no-thinking Disable thinking mode"
echo " --no-format Disable format enhancement"
echo " --duration Duration in seconds"
echo " --bpm Beats per minute"
echo " --key-scale Musical key (e.g. \"E minor\")"
echo " --time-signature Time signature (e.g. \"4/4\")"
echo ""
echo "Cover/Repainting Options:"
echo " --src-audio Source audio file path"
echo " --task-type Task type: cover, repaint, text2music (default: auto)"
echo " --cover-strength Cover strength 0.0-1.0 (default: 1.0)"
echo " --repaint-start Repainting start position in seconds"
echo " --repaint-end Repainting end position in seconds"
echo ""
echo "Examples:"
echo " $0 generate \"Pop music with guitar\" # Caption mode"
echo " $0 generate -d \"A February love song\" # Simple mode (LM generates)"
echo " $0 generate -c \"Jazz\" -l \"[Verse] Hello\" # With lyrics"
echo " $0 cover song.mp3 -c \"Rock cover\" -l \"[Verse] ...\" --duration 120"
echo " $0 generate --src-audio song.mp3 --task-type repaint -c \"Pop\" --repaint-start 30 --repaint-end 60"
echo " $0 random"
echo " $0 status <job_id>"
echo " $0 config --set generation.thinking false"
}
# Main
case "$1" in
generate) shift; cmd_generate "$@" ;;
cover) shift; cmd_cover "$@" ;;
random) shift; cmd_random "$@" ;;
status) shift; cmd_status "$@" ;;
models) cmd_models ;;
health) cmd_health ;;
config) shift; cmd_config "$@" ;;
help|--help|-h) show_help ;;
*) show_help; exit 1 ;;
esac
================================================
FILE: .claude/skills/acestep/scripts/config.example.json
================================================
{
"api_url": "https://api.acemusic.ai",
"api_key": "",
"api_mode": "completion",
"generation": {
"thinking": true,
"use_format": false,
"use_cot_caption": true,
"use_cot_language": false,
"audio_format": "mp3",
"batch_size": 1,
"vocal_language": "en"
}
}
================================================
FILE: .claude/skills/acestep-docs/SKILL.md
================================================
---
name: acestep-docs
description: ACE-Step documentation and troubleshooting. Use when users ask about installing ACE-Step, GPU configuration, model download, Gradio UI usage, API integration, or troubleshooting issues like VRAM problems, CUDA errors, or model loading failures.
allowed-tools: Read, Glob, Grep
---
# ACE-Step Documentation
Documentation skill for ACE-Step music generation system.
## Quick Reference
### Getting Started
| Document | Description |
|----------|-------------|
| [README.md](getting-started/README.md) | Installation, model download, startup commands |
| [Tutorial.md](getting-started/Tutorial.md) | Getting started tutorial, best practices |
| [ABOUT.md](getting-started/ABOUT.md) | Project overview, architecture, model zoo |
### Guides
| Document | Description |
|----------|-------------|
| [GRADIO_GUIDE.md](guides/GRADIO_GUIDE.md) | Web UI usage guide |
| [INFERENCE.md](guides/INFERENCE.md) | Inference parameters tuning |
| [GPU_COMPATIBILITY.md](guides/GPU_COMPATIBILITY.md) | GPU/VRAM configuration, hardware recommendations |
| [ENVIRONMENT_SETUP.md](guides/ENVIRONMENT_SETUP.md) | Environment detection, uv installation, python_embeded setup (Windows/Linux/macOS) |
| [SCRIPT_CONFIGURATION.md](guides/SCRIPT_CONFIGURATION.md) | Configuring launch scripts: .bat (Windows) and .sh (Linux/macOS) |
| [UPDATE_AND_BACKUP.md](guides/UPDATE_AND_BACKUP.md) | Git updates, file backup, conflict resolution (all platforms) |
### API (for developers)
| Document | Description |
|----------|-------------|
| [API.md](api/API.md) | REST API documentation |
| [Openrouter_API.md](api/Openrouter_API.md) | OpenRouter API integration |
## Instructions
1. Installation questions → read [getting-started/README.md](getting-started/README.md)
2. General usage / best practices → read [getting-started/Tutorial.md](getting-started/Tutorial.md)
3. Project overview / architecture → read [getting-started/ABOUT.md](getting-started/ABOUT.md)
4. Web UI questions → read [guides/GRADIO_GUIDE.md](guides/GRADIO_GUIDE.md)
5. Inference parameter tuning → read [guides/INFERENCE.md](guides/INFERENCE.md)
6. GPU/VRAM issues → read [guides/GPU_COMPATIBILITY.md](guides/GPU_COMPATIBILITY.md)
7. Environment setup (uv, python_embeded) → read [guides/ENVIRONMENT_SETUP.md](guides/ENVIRONMENT_SETUP.md)
8. Launch script configuration (.bat/.sh) → read [guides/SCRIPT_CONFIGURATION.md](guides/SCRIPT_CONFIGURATION.md)
9. Updates and backup → read [guides/UPDATE_AND_BACKUP.md](guides/UPDATE_AND_BACKUP.md)
10. API development → read [api/API.md](api/API.md) or [api/Openrouter_API.md](api/Openrouter_API.md)
## Common Issues
- **Installation problems**: See getting-started/README.md
- **VRAM insufficient**: See guides/GPU_COMPATIBILITY.md
- **Model download failed**: See getting-started/README.md or guides/SCRIPT_CONFIGURATION.md
- **uv not found**: See guides/ENVIRONMENT_SETUP.md
- **Environment detection issues**: See guides/ENVIRONMENT_SETUP.md
- **BAT/SH script configuration**: See guides/SCRIPT_CONFIGURATION.md
- **Update and backup**: See guides/UPDATE_AND_BACKUP.md
- **Update conflicts**: See guides/UPDATE_AND_BACKUP.md
- **Inference quality issues**: See guides/INFERENCE.md
- **Gradio UI not starting**: See guides/GRADIO_GUIDE.md
================================================
FILE: .claude/skills/acestep-docs/api/API.md
================================================
# ACE-Step API Client Documentation
---
This service provides an HTTP-based asynchronous music generation API.
**Basic Workflow**:
1. Call `POST /release_task` to submit a task and obtain a `task_id`.
2. Call `POST /query_result` to batch query task status until `status` is `1` (succeeded) or `2` (failed).
3. Download audio files via `GET /v1/audio?path=...` URLs returned in the result.
---
## Table of Contents
- [Authentication](#1-authentication)
- [Response Format](#2-response-format)
- [Task Status Description](#3-task-status-description)
- [Create Generation Task](#4-create-generation-task)
- [Batch Query Task Results](#5-batch-query-task-results)
- [Format Input](#6-format-input)
- [Get Random Sample](#7-get-random-sample)
- [List Available Models](#8-list-available-models)
- [Server Statistics](#9-server-statistics)
- [Download Audio Files](#10-download-audio-files)
- [Health Check](#11-health-check)
- [Environment Variables](#12-environment-variables)
---
## 1. Authentication
The API supports optional API key authentication. When enabled, a valid key must be provided in requests.
### Authentication Methods
Two authentication methods are supported:
**Method A: ai_token in request body**
```json
{
"ai_token": "your-api-key",
"prompt": "upbeat pop song",
...
}
```
**Method B: Authorization header**
```bash
curl -X POST http://localhost:8001/release_task \
-H 'Authorization: Bearer your-api-key' \
-H 'Content-Type: application/json' \
-d '{"prompt": "upbeat pop song"}'
```
### Configuring API Key
Set via environment variable or command-line argument:
```bash
# Environment variable
export ACESTEP_API_KEY=your-secret-key
# Or command-line argument
python -m acestep.api_server --api-key your-secret-key
```
---
## 2. Response Format
All API responses use a unified wrapper format:
```json
{
"data": { ... },
"code": 200,
"error": null,
"timestamp": 1700000000000,
"extra": null
}
```
| Field | Type | Description |
| :--- | :--- | :--- |
| `data` | any | Actual response data |
| `code` | int | Status code (200=success) |
| `error` | string | Error message (null on success) |
| `timestamp` | int | Response timestamp (milliseconds) |
| `extra` | any | Extra information (usually null) |
---
## 3. Task Status Description
Task status (`status`) is represented as integers:
| Status Code | Status Name | Description |
| :--- | :--- | :--- |
| `0` | queued/running | Task is queued or in progress |
| `1` | succeeded | Generation succeeded, result is ready |
| `2` | failed | Generation failed |
---
## 4. Create Generation Task
### 4.1 API Definition
- **URL**: `/release_task`
- **Method**: `POST`
- **Content-Type**: `application/json`, `multipart/form-data`, or `application/x-www-form-urlencoded`
### 4.2 Request Parameters
#### Parameter Naming Convention
The API supports both **snake_case** and **camelCase** naming for most parameters. For example:
- `audio_duration` / `duration` / `audioDuration`
- `key_scale` / `keyscale` / `keyScale`
- `time_signature` / `timesignature` / `timeSignature`
- `sample_query` / `sampleQuery` / `description` / `desc`
- `use_format` / `useFormat` / `format`
Additionally, metadata can be passed in a nested object (`metas`, `metadata`, or `user_metadata`).
#### Method A: JSON Request (application/json)
Suitable for passing only text parameters, or referencing audio file paths that already exist on the server.
**Basic Parameters**:
| Parameter Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `prompt` | string | `""` | Music description prompt (alias: `caption`) |
| `lyrics` | string | `""` | Lyrics content |
| `thinking` | bool | `false` | Whether to use 5Hz LM to generate audio codes (lm-dit behavior) |
| `vocal_language` | string | `"en"` | Lyrics language (en, zh, ja, etc.) |
| `audio_format` | string | `"mp3"` | Output format (mp3, wav, flac) |
**Sample/Description Mode Parameters**:
| Parameter Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `sample_mode` | bool | `false` | Enable random sample generation mode (auto-generates caption/lyrics/metas via LM) |
| `sample_query` | string | `""` | Natural language description for sample generation (e.g., "a soft Bengali love song"). Aliases: `description`, `desc` |
| `use_format` | bool | `false` | Use LM to enhance/format the provided caption and lyrics. Alias: `format` |
**Multi-Model Support**:
| Parameter Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `model` | string | null | Select which DiT model to use (e.g., `"acestep-v15-turbo"`, `"acestep-v15-turbo-shift3"`). Use `/v1/models` to list available models. If not specified, uses the default model. |
**thinking Semantics (Important)**:
- `thinking=false`:
- The server will **NOT** use 5Hz LM to generate `audio_code_string`.
- DiT runs in **text2music** mode and **ignores** any provided `audio_code_string`.
- `thinking=true`:
- The server will use 5Hz LM to generate `audio_code_string` (lm-dit behavior).
- DiT runs with LM-generated codes for enhanced music quality.
**Metadata Auto-Completion (Conditional)**:
When `use_cot_caption=true` or `use_cot_language=true` or metadata fields are missing, the server may call 5Hz LM to fill the missing fields based on `caption`/`lyrics`:
- `bpm`
- `key_scale`
- `time_signature`
- `audio_duration`
User-provided values always win; LM only fills the fields that are empty/missing.
**Music Attribute Parameters**:
| Parameter Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `bpm` | int | null | Specify tempo (BPM), range 30-300 |
| `key_scale` | string | `""` | Key/scale (e.g., "C Major", "Am"). Aliases: `keyscale`, `keyScale` |
| `time_signature` | string | `""` | Time signature (2, 3, 4, 6 for 2/4, 3/4, 4/4, 6/8). Aliases: `timesignature`, `timeSignature` |
| `audio_duration` | float | null | Generation duration (seconds), range 10-600. Aliases: `duration`, `target_duration` |
**Audio Codes (Optional)**:
| Parameter Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `audio_code_string` | string or string[] | `""` | Audio semantic tokens (5Hz) for `llm_dit`. Alias: `audioCodeString` |
**Generation Control Parameters**:
| Parameter Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `inference_steps` | int | `8` | Number of inference steps. Turbo model: 1-20 (recommended 8). Base model: 1-200 (recommended 32-64). |
| `guidance_scale` | float | `7.0` | Prompt guidance coefficient. Only effective for base model. |
| `use_random_seed` | bool | `true` | Whether to use random seed |
| `seed` | int | `-1` | Specify seed (when use_random_seed=false) |
| `batch_size` | int | `2` | Batch generation count (max 8) |
**Advanced DiT Parameters**:
| Parameter Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `shift` | float | `3.0` | Timestep shift factor (range 1.0-5.0). Only effective for base models, not turbo models. |
| `infer_method` | string | `"ode"` | Diffusion inference method: `"ode"` (Euler, faster) or `"sde"` (stochastic). |
| `timesteps` | string | null | Custom timesteps as comma-separated values (e.g., `"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0"`). Overrides `inference_steps` and `shift`. |
| `use_adg` | bool | `false` | Use Adaptive Dual Guidance (base model only) |
| `cfg_interval_start` | float | `0.0` | CFG application start ratio (0.0-1.0) |
| `cfg_interval_end` | float | `1.0` | CFG application end ratio (0.0-1.0) |
**5Hz LM Parameters (Optional, server-side)**:
These parameters control 5Hz LM sampling, used for metadata auto-completion and (when `thinking=true`) codes generation.
| Parameter Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `lm_model_path` | string | null | 5Hz LM checkpoint dir name (e.g. `acestep-5Hz-lm-0.6B`) |
| `lm_backend` | string | `"vllm"` | `vllm` or `pt` |
| `lm_temperature` | float | `0.85` | Sampling temperature |
| `lm_cfg_scale` | float | `2.5` | CFG scale (>1 enables CFG) |
| `lm_negative_prompt` | string | `"NO USER INPUT"` | Negative prompt used by CFG |
| `lm_top_k` | int | null | Top-k (0/null disables) |
| `lm_top_p` | float | `0.9` | Top-p (>=1 will be treated as disabled) |
| `lm_repetition_penalty` | float | `1.0` | Repetition penalty |
**LM CoT (Chain-of-Thought) Parameters**:
| Parameter Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `use_cot_caption` | bool | `true` | Let LM rewrite/enhance the input caption via CoT reasoning. Aliases: `cot_caption`, `cot-caption` |
| `use_cot_language` | bool | `true` | Let LM detect vocal language via CoT. Aliases: `cot_language`, `cot-language` |
| `constrained_decoding` | bool | `true` | Enable FSM-based constrained decoding for structured LM output. Aliases: `constrainedDecoding`, `constrained` |
| `constrained_decoding_debug` | bool | `false` | Enable debug logging for constrained decoding |
| `allow_lm_batch` | bool | `true` | Allow LM batch processing for efficiency |
**Edit/Reference Audio Parameters** (requires absolute path on server):
| Parameter Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `reference_audio_path` | string | null | Reference audio path (Style Transfer) |
| `src_audio_path` | string | null | Source audio path (Repainting/Cover) |
| `task_type` | string | `"text2music"` | Task type: `text2music`, `cover`, `repaint`, `lego`, `extract`, `complete` |
| `instruction` | string | auto | Edit instruction (auto-generated based on task_type if not provided) |
| `repainting_start` | float | `0.0` | Repainting start time (seconds) |
| `repainting_end` | float | null | Repainting end time (seconds), -1 for end of audio |
| `audio_cover_strength` | float | `1.0` | Cover strength (0.0-1.0). Lower values (0.2) for style transfer. |
#### Method B: File Upload (multipart/form-data)
Use this when you need to upload local audio files as reference or source audio.
In addition to supporting all the above fields as Form Fields, the following file fields are also supported:
- `reference_audio` or `ref_audio`: (File) Upload reference audio file
- `src_audio` or `ctx_audio`: (File) Upload source audio file
> **Note**: After uploading files, the corresponding `_path` parameters will be automatically ignored, and the system will use the temporary file path after upload.
### 4.3 Response Example
```json
{
"data": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued",
"queue_position": 1
},
"code": 200,
"error": null,
"timestamp": 1700000000000,
"extra": null
}
```
### 4.4 Usage Examples (cURL)
**Basic JSON Method**:
```bash
curl -X POST http://localhost:8001/release_task \
-H 'Content-Type: application/json' \
-d '{
"prompt": "upbeat pop song",
"lyrics": "Hello world",
"inference_steps": 8
}'
```
**With thinking=true (LM generates codes + fills missing metas)**:
```bash
curl -X POST http://localhost:8001/release_task \
-H 'Content-Type: application/json' \
-d '{
"prompt": "upbeat pop song",
"lyrics": "Hello world",
"thinking": true,
"lm_temperature": 0.85,
"lm_cfg_scale": 2.5
}'
```
**Description-driven generation (sample_query)**:
```bash
curl -X POST http://localhost:8001/release_task \
-H 'Content-Type: application/json' \
-d '{
"sample_query": "a soft Bengali love song for a quiet evening",
"thinking": true
}'
```
**With format enhancement (use_format=true)**:
```bash
curl -X POST http://localhost:8001/release_task \
-H 'Content-Type: application/json' \
-d '{
"prompt": "pop rock",
"lyrics": "[Verse 1]\nWalking down the street...",
"use_format": true,
"thinking": true
}'
```
**Select specific model**:
```bash
curl -X POST http://localhost:8001/release_task \
-H 'Content-Type: application/json' \
-d '{
"prompt": "electronic dance music",
"model": "acestep-v15-turbo",
"thinking": true
}'
```
**With custom timesteps**:
```bash
curl -X POST http://localhost:8001/release_task \
-H 'Content-Type: application/json' \
-d '{
"prompt": "jazz piano trio",
"timesteps": "0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0",
"thinking": true
}'
```
**File Upload Method**:
```bash
curl -X POST http://localhost:8001/release_task \
-F "prompt=remix this song" \
-F "src_audio=@/path/to/local/song.mp3" \
-F "task_type=repaint"
```
---
## 5. Batch Query Task Results
### 5.1 API Definition
- **URL**: `/query_result`
- **Method**: `POST`
- **Content-Type**: `application/json` or `application/x-www-form-urlencoded`
### 5.2 Request Parameters
| Parameter Name | Type | Description |
| :--- | :--- | :--- |
| `task_id_list` | string (JSON array) or array | List of task IDs to query |
### 5.3 Response Example
```json
{
"data": [
{
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": 1,
"result": "[{\"file\": \"/v1/audio?path=...\", \"wave\": \"\", \"status\": 1, \"create_time\": 1700000000, \"env\": \"development\", \"prompt\": \"upbeat pop song\", \"lyrics\": \"Hello world\", \"metas\": {\"bpm\": 120, \"duration\": 30, \"genres\": \"\", \"keyscale\": \"C Major\", \"timesignature\": \"4\"}, \"generation_info\": \"...\", \"seed_value\": \"12345,67890\", \"lm_model\": \"acestep-5Hz-lm-0.6B\", \"dit_model\": \"acestep-v15-turbo\"}]"
}
],
"code": 200,
"error": null,
"timestamp": 1700000000000,
"extra": null
}
```
**Result Field Description** (result is a JSON string, after parsing contains):
| Field | Type | Description |
| :--- | :--- | :--- |
| `file` | string | Audio file URL (use with `/v1/audio` endpoint) |
| `wave` | string | Waveform data (usually empty) |
| `status` | int | Status code (0=in progress, 1=success, 2=failed) |
| `create_time` | int | Creation time (Unix timestamp) |
| `env` | string | Environment identifier |
| `prompt` | string | Prompt used |
| `lyrics` | string | Lyrics used |
| `metas` | object | Metadata (bpm, duration, genres, keyscale, timesignature) |
| `generation_info` | string | Generation info summary |
| `seed_value` | string | Seed values used (comma-separated) |
| `lm_model` | string | LM model name used |
| `dit_model` | string | DiT model name used |
### 5.4 Usage Example
```bash
curl -X POST http://localhost:8001/query_result \
-H 'Content-Type: application/json' \
-d '{
"task_id_list": ["550e8400-e29b-41d4-a716-446655440000"]
}'
```
---
## 6. Format Input
### 6.1 API Definition
- **URL**: `/format_input`
- **Method**: `POST`
This endpoint uses LLM to enhance and format user-provided caption and lyrics.
### 6.2 Request Parameters
| Parameter Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `prompt` | string | `""` | Music description prompt |
| `lyrics` | string | `""` | Lyrics content |
| `temperature` | float | `0.85` | LM sampling temperature |
| `param_obj` | string (JSON) | `"{}"` | JSON object containing metadata (duration, bpm, key, time_signature, language) |
### 6.3 Response Example
```json
{
"data": {
"caption": "Enhanced music description",
"lyrics": "Formatted lyrics...",
"bpm": 120,
"key_scale": "C Major",
"time_signature": "4",
"duration": 180,
"vocal_language": "en"
},
"code": 200,
"error": null,
"timestamp": 1700000000000,
"extra": null
}
```
### 6.4 Usage Example
```bash
curl -X POST http://localhost:8001/format_input \
-H 'Content-Type: application/json' \
-d '{
"prompt": "pop rock",
"lyrics": "Walking down the street",
"param_obj": "{\"duration\": 180, \"language\": \"en\"}"
}'
```
---
## 7. Get Random Sample
### 7.1 API Definition
- **URL**: `/create_random_sample`
- **Method**: `POST`
This endpoint returns random sample parameters from pre-loaded example data for form filling.
### 7.2 Request Parameters
| Parameter Name | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `sample_type` | string | `"simple_mode"` | Sample type: `"simple_mode"` or `"custom_mode"` |
### 7.3 Response Example
```json
{
"data": {
"caption": "Upbeat pop song with guitar accompaniment",
"lyrics": "[Verse 1]\nSunshine on my face...",
"bpm": 120,
"key_scale": "G Major",
"time_signature": "4",
"duration": 180,
"vocal_language": "en"
},
"code": 200,
"error": null,
"timestamp": 1700000000000,
"extra": null
}
```
### 7.4 Usage Example
```bash
curl -X POST http://localhost:8001/create_random_sample \
-H 'Content-Type: application/json' \
-d '{"sample_type": "simple_mode"}'
```
---
## 8. List Available Models
### 8.1 API Definition
- **URL**: `/v1/models`
- **Method**: `GET`
Returns a list of available DiT models loaded on the server.
### 8.2 Response Example
```json
{
"data": {
"models": [
{
"name": "acestep-v15-turbo",
"is_default": true
},
{
"name": "acestep-v15-turbo-shift3",
"is_default": false
}
],
"default_model": "acestep-v15-turbo"
},
"code": 200,
"error": null,
"timestamp": 1700000000000,
"extra": null
}
```
### 8.3 Usage Example
```bash
curl http://localhost:8001/v1/models
```
---
## 9. Server Statistics
### 9.1 API Definition
- **URL**: `/v1/stats`
- **Method**: `GET`
Returns server runtime statistics.
### 9.2 Response Example
```json
{
"data": {
"jobs": {
"total": 100,
"queued": 5,
"running": 1,
"succeeded": 90,
"failed": 4
},
"queue_size": 5,
"queue_maxsize": 200,
"avg_job_seconds": 8.5
},
"code": 200,
"error": null,
"timestamp": 1700000000000,
"extra": null
}
```
### 9.3 Usage Example
```bash
curl http://localhost:8001/v1/stats
```
---
## 10. Download Audio Files
### 10.1 API Definition
- **URL**: `/v1/audio`
- **Method**: `GET`
Download generated audio files by path.
### 10.2 Request Parameters
| Parameter Name | Type | Description |
| :--- | :--- | :--- |
| `path` | string | URL-encoded path to the audio file |
### 10.3 Usage Example
```bash
# Download using the URL from task result
curl "http://localhost:8001/v1/audio?path=%2Ftmp%2Fapi_audio%2Fabc123.mp3" -o output.mp3
```
---
## 11. Health Check
### 11.1 API Definition
- **URL**: `/health`
- **Method**: `GET`
Returns service health status.
### 11.2 Response Example
```json
{
"data": {
"status": "ok",
"service": "ACE-Step API",
"version": "1.0"
},
"code": 200,
"error": null,
"timestamp": 1700000000000,
"extra": null
}
```
---
## 12. Environment Variables
The API server can be configured using environment variables:
### Server Configuration
| Variable | Default | Description |
| :--- | :--- | :--- |
| `ACESTEP_API_HOST` | `127.0.0.1` | Server bind host |
| `ACESTEP_API_PORT` | `8001` | Server bind port |
| `ACESTEP_API_KEY` | (empty) | API authentication key (empty disables auth) |
| `ACESTEP_API_WORKERS` | `1` | API worker thread count |
### Model Configuration
| Variable | Default | Description |
| :--- | :--- | :--- |
| `ACESTEP_CONFIG_PATH` | `acestep-v15-turbo` | Primary DiT model path |
| `ACESTEP_CONFIG_PATH2` | (empty) | Secondary DiT model path (optional) |
| `ACESTEP_CONFIG_PATH3` | (empty) | Third DiT model path (optional) |
| `ACESTEP_DEVICE` | `auto` | Device for model loading |
| `ACESTEP_USE_FLASH_ATTENTION` | `true` | Enable flash attention |
| `ACESTEP_OFFLOAD_TO_CPU` | `false` | Offload models to CPU when idle |
| `ACESTEP_OFFLOAD_DIT_TO_CPU` | `false` | Offload DiT specifically to CPU |
### LM Configuration
| Variable | Default | Description |
| :--- | :--- | :--- |
| `ACESTEP_INIT_LLM` | auto | Whether to initialize LM at startup (auto determines based on GPU) |
| `ACESTEP_LM_MODEL_PATH` | `acestep-5Hz-lm-0.6B` | Default 5Hz LM model |
| `ACESTEP_LM_BACKEND` | `vllm` | LM backend (vllm or pt) |
| `ACESTEP_LM_DEVICE` | (same as ACESTEP_DEVICE) | Device for LM |
| `ACESTEP_LM_OFFLOAD_TO_CPU` | `false` | Offload LM to CPU |
### Queue Configuration
| Variable | Default | Description |
| :--- | :--- | :--- |
| `ACESTEP_QUEUE_MAXSIZE` | `200` | Maximum queue size |
| `ACESTEP_QUEUE_WORKERS` | `1` | Number of queue workers |
| `ACESTEP_AVG_JOB_SECONDS` | `5.0` | Initial average job duration estimate |
| `ACESTEP_AVG_WINDOW` | `50` | Window for averaging job duration |
### Cache Configuration
| Variable | Default | Description |
| :--- | :--- | :--- |
| `ACESTEP_TMPDIR` | `.cache/acestep/tmp` | Temporary file directory |
| `TRITON_CACHE_DIR` | `.cache/acestep/triton` | Triton cache directory |
| `TORCHINDUCTOR_CACHE_DIR` | `.cache/acestep/torchinductor` | TorchInductor cache directory |
---
## Error Handling
**HTTP Status Codes**:
- `200`: Success
- `400`: Invalid request (bad JSON, missing fields)
- `401`: Unauthorized (missing or invalid API key)
- `404`: Resource not found
- `415`: Unsupported Content-Type
- `429`: Server busy (queue is full)
- `500`: Internal server error
**Error Response Format**:
```json
{
"detail": "Error message describing the issue"
}
```
---
## Best Practices
1. **Use `thinking=true`** for best quality results with LM-enhanced generation.
2. **Use `sample_query`/`description`** for quick generation from natural language descriptions.
3. **Use `use_format=true`** when you have caption/lyrics but want LM to enhance them.
4. **Batch query task status** using the `/query_result` endpoint to query multiple tasks at once.
5. **Check `/v1/stats`** to understand server load and average job time.
6. **Use multi-model support** by setting `ACESTEP_CONFIG_PATH2` and `ACESTEP_CONFIG_PATH3` environment variables, then select with the `model` parameter.
7. **For production**, set `ACESTEP_API_KEY` to enable authentication and secure your API.
8. **For low VRAM environments**, enable `ACESTEP_OFFLOAD_TO_CPU=true` to support longer audio generation.
================================================
FILE: .claude/skills/acestep-docs/api/Openrouter_API.md
================================================
# ACE-Step OpenRouter API Documentation
> OpenAI Chat Completions-compatible API for AI music generation
**Base URL:** `http://{host}:{port}` (default `http://127.0.0.1:8002`)
---
## Table of Contents
- [Authentication](#authentication)
- [Endpoints](#endpoints)
- [POST /v1/chat/completions - Generate Music](#1-generate-music)
- [GET /api/v1/models - List Models](#2-list-models)
- [GET /health - Health Check](#3-health-check)
- [Input Modes](#input-modes)
- [Streaming Responses](#streaming-responses)
- [Examples](#examples)
- [Error Codes](#error-codes)
---
## Authentication
If the server is configured with an API key (via the `OPENROUTER_API_KEY` environment variable or `--api-key` CLI flag), all requests must include the following header:
```
Authorization: Bearer <your-api-key>
```
No authentication is required when no API key is configured.
---
## Endpoints
### 1. Generate Music
**POST** `/v1/chat/completions`
Generates music from chat messages and returns audio data along with LM-generated metadata.
#### Request Parameters
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `model` | string | No | `"acemusic/acestep-v1.5-turbo"` | Model ID |
| `messages` | array | **Yes** | - | Chat message list. See [Input Modes](#input-modes) |
| `stream` | boolean | No | `false` | Enable streaming response. See [Streaming Responses](#streaming-responses) |
| `temperature` | float | No | `0.85` | LM sampling temperature |
| `top_p` | float | No | `0.9` | LM nucleus sampling parameter |
| `lyrics` | string | No | `""` | Lyrics passed directly (takes priority over lyrics parsed from messages) |
| `duration` | float | No | `null` | Audio duration in seconds. If omitted, determined automatically by the LM |
| `bpm` | integer | No | `null` | Beats per minute. If omitted, determined automatically by the LM |
| `vocal_language` | string | No | `"en"` | Vocal language code (e.g. `"zh"`, `"en"`, `"ja"`) |
| `instrumental` | boolean | No | `false` | Whether to generate instrumental-only music (no vocals) |
| `thinking` | boolean | No | `false` | Enable LLM thinking mode for deeper reasoning |
| `use_cot_metas` | boolean | No | `true` | Auto-generate BPM, duration, key, time signature via Chain-of-Thought |
| `use_cot_caption` | boolean | No | `true` | Rewrite/enhance the music description via Chain-of-Thought |
| `use_cot_language` | boolean | No | `true` | Auto-detect vocal language via Chain-of-Thought |
| `use_format` | boolean | No | `true` | When prompt/lyrics are provided directly, enhance them via LLM formatting |
> **Note on LM parameters:** `use_format` applies when the user provides explicit prompt/lyrics (tagged or lyrics mode) and enhances the description and lyrics formatting via LLM. The `use_cot_*` parameters control Phase 1 CoT reasoning during the audio generation stage. When `use_format` or sample mode has already generated a duration, `use_cot_metas` is automatically skipped to avoid redundancy.
#### messages Format
```json
{
"messages": [
{
"role": "user",
"content": "Your input content"
}
]
}
```
Set `role` to `"user"` and `content` to the text input. The system automatically determines the input mode based on the content. See [Input Modes](#input-modes) for details.
---
#### Non-Streaming Response (`stream: false`)
```json
{
"id": "chatcmpl-a1b2c3d4e5f6g7h8",
"object": "chat.completion",
"created": 1706688000,
"model": "acemusic/acestep-v1.5-turbo",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "## Metadata\n**Caption:** Upbeat pop song...\n**BPM:** 120\n**Duration:** 30s\n**Key:** C major\n\n## Lyrics\n[Verse 1]\nHello world...",
"audio": [
{
"type": "audio_url",
"audio_url": {
"url": "data:audio/mpeg;base64,SUQzBAAAAAAAI1RTU0UAAAA..."
}
}
]
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 100,
"total_tokens": 110
}
}
```
**Response Fields:**
| Field | Description |
|---|---|
| `choices[0].message.content` | Text information generated by the LM, including Metadata (Caption, BPM, Duration, Key, Time Signature, Language) and Lyrics. Returns `"Music generated successfully."` if LM was not involved |
| `choices[0].message.audio` | Audio data array. Each item contains `type` (`"audio_url"`) and `audio_url.url` (Base64 Data URL in format `data:audio/mpeg;base64,...`) |
| `choices[0].finish_reason` | `"stop"` indicates normal completion |
**Decoding Audio:**
The `audio_url.url` value is a Data URL: `data:audio/mpeg;base64,<base64_data>`
Extract the base64 portion after the comma and decode it to get the MP3 file:
```python
import base64
url = response["choices"][0]["message"]["audio"][0]["audio_url"]["url"]
# Strip the "data:audio/mpeg;base64," prefix
b64_data = url.split(",", 1)[1]
audio_bytes = base64.b64decode(b64_data)
with open("output.mp3", "wb") as f:
f.write(audio_bytes)
```
```javascript
const url = response.choices[0].message.audio[0].audio_url.url;
const b64Data = url.split(",")[1];
const audioBytes = atob(b64Data);
// Or use the Data URL directly in an <audio> element
const audio = new Audio(url);
audio.play();
```
---
### 2. List Models
**GET** `/api/v1/models`
Returns available model information.
#### Response
```json
{
"data": [
{
"id": "acemusic/acestep-v1.5-turbo",
"name": "ACE-Step",
"created": 1706688000,
"description": "High-performance text-to-music generation model...",
"input_modalities": ["text"],
"output_modalities": ["audio"],
"context_length": 4096,
"pricing": {
"prompt": "0",
"completion": "0",
"request": "0"
},
"supported_sampling_parameters": ["temperature", "top_p"]
}
]
}
```
---
### 3. Health Check
**GET** `/health`
#### Response
```json
{
"status": "ok",
"service": "ACE-Step OpenRouter API",
"version": "1.0"
}
```
---
## Input Modes
The system automatically selects the input mode based on the content of the last `user` message:
### Mode 1: Tagged Mode (Recommended)
Use `<prompt>` and `<lyrics>` tags to explicitly specify the music description and lyrics:
```json
{
"messages": [
{
"role": "user",
"content": "<prompt>A gentle acoustic ballad in C major, 80 BPM, female vocal</prompt>\n<lyrics>[Verse 1]\nSunlight through the window\nA brand new day begins\n\n[Chorus]\nWe are the dreamers\nWe are the light</lyrics>"
}
]
}
```
- `<prompt>...</prompt>` - Music style/scene description (caption)
- `<lyrics>...</lyrics>` - Lyrics content
- Either tag can be used alone
- When `use_format=true`, the LLM automatically enhances both prompt and lyrics
### Mode 2: Natural Language Mode (Sample Mode)
Describe the desired music in natural language. The system uses LLM to generate the prompt and lyrics automatically:
```json
{
"messages": [
{
"role": "user",
"content": "Generate an upbeat pop song about summer and travel"
}
]
}
```
**Trigger condition:** Message content contains no tags and does not resemble lyrics (no `[Verse]`/`[Chorus]` markers, few lines, or long single lines).
### Mode 3: Lyrics-Only Mode
Pass in lyrics with structural markers directly. The system identifies them automatically:
```json
{
"messages": [
{
"role": "user",
"content": "[Verse 1]\nWalking down the street\nFeeling the beat\n\n[Chorus]\nDance with me tonight\nUnder the moonlight"
}
]
}
```
**Trigger condition:** Message content contains `[Verse]`, `[Chorus]`, or similar markers, or has a multi-line short-text structure.
### Instrumental Mode
Set `instrumental: true` or use `[inst]` as the lyrics:
```json
{
"instrumental": true,
"messages": [
{
"role": "user",
"content": "<prompt>Epic orchestral cinematic score, dramatic and powerful</prompt>"
}
]
}
```
---
## Streaming Responses
Set `"stream": true` to enable SSE (Server-Sent Events) streaming.
### Event Format
Each event starts with `data: `, followed by JSON, ending with a double newline `\n\n`:
```
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1706688000,"model":"acemusic/acestep-v1.5-turbo","choices":[{"index":0,"delta":{...},"finish_reason":null}]}
```
### Streaming Event Sequence
| Phase | Delta Content | Description |
|---|---|---|
| 1. Initialization | `{"role":"assistant","content":""}` | Establishes the connection |
| 2. LM Content (optional) | `{"content":"## Metadata\n..."}` | Metadata and lyrics generated by the LM |
| 3. Heartbeat | `{"content":"."}` | Sent every 2 seconds during audio generation to keep the connection alive |
| 4. Audio Data | `{"audio":[{"type":"audio_url","audio_url":{"url":"data:..."}}]}` | The generated audio |
| 5. Finish | `finish_reason: "stop"` | Generation complete |
| 6. Termination | `data: [DONE]` | End-of-stream marker |
### Streaming Response Example
```
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1706688000,"model":"acemusic/acestep-v1.5-turbo","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1706688000,"model":"acemusic/acestep-v1.5-turbo","choices":[{"index":0,"delta":{"content":"\n\n## Metadata\n**Caption:** Upbeat pop\n**BPM:** 120"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1706688000,"model":"acemusic/acestep-v1.5-turbo","choices":[{"index":0,"delta":{"content":"."},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1706688000,"model":"acemusic/acestep-v1.5-turbo","choices":[{"index":0,"delta":{"audio":[{"type":"audio_url","audio_url":{"url":"data:audio/mpeg;base64,..."}}]},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1706688000,"model":"acemusic/acestep-v1.5-turbo","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
```
### Client-Side Streaming Handling
```python
import json
import httpx
with httpx.stream("POST", "http://127.0.0.1:8002/v1/chat/completions", json={
"messages": [{"role": "user", "content": "Generate a cheerful guitar piece"}],
"stream": True
}) as response:
content_parts = []
audio_url = None
for line in response.iter_lines():
if not line or not line.startswith("data: "):
continue
if line == "data: [DONE]":
break
chunk = json.loads(line[6:])
delta = chunk["choices"][0]["delta"]
if "content" in delta and delta["content"]:
content_parts.append(delta["content"])
if "audio" in delta and delta["audio"]:
audio_url = delta["audio"][0]["audio_url"]["url"]
if chunk["choices"][0].get("finish_reason") == "stop":
print("Generation complete!")
print("Content:", "".join(content_parts))
if audio_url:
import base64
b64_data = audio_url.split(",", 1)[1]
with open("output.mp3", "wb") as f:
f.write(base64.b64decode(b64_data))
```
```javascript
const response = await fetch("http://127.0.0.1:8002/v1/chat/completions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
messages: [{ role: "user", content: "Generate a cheerful guitar piece" }],
stream: true
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
let audioUrl = null;
let content = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value);
for (const line of text.split("\n")) {
if (!line.startsWith("data: ") || line === "data: [DONE]") continue;
const chunk = JSON.parse(line.slice(6));
const delta = chunk.choices[0].delta;
if (delta.content) content += delta.content;
if (delta.audio) audioUrl = delta.audio[0].audio_url.url;
}
}
// audioUrl can be used directly as <audio src="...">
```
---
## Examples
### Example 1: Natural Language Generation (Simplest Usage)
```bash
curl -X POST http://127.0.0.1:8002/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "A soft folk song about hometown and memories"}
],
"vocal_language": "en"
}'
```
### Example 2: Tagged Mode with Specific Parameters
```bash
curl -X POST http://127.0.0.1:8002/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"role": "user",
"content": "<prompt>Energetic EDM track with heavy bass drops and synth leads</prompt><lyrics>[Verse 1]\nFeel the rhythm in your soul\nLet the music take control\n\n[Drop]\n(instrumental break)</lyrics>"
}
],
"bpm": 128,
"duration": 60,
"vocal_language": "en"
}'
```
### Example 3: Instrumental with LM Enhancement Disabled
```bash
curl -X POST http://127.0.0.1:8002/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"role": "user",
"content": "<prompt>Peaceful piano solo, slow tempo, jazz harmony</prompt>"
}
],
"instrumental": true,
"use_format": false,
"use_cot_caption": false,
"duration": 45
}'
```
### Example 4: Streaming Request
```bash
curl -X POST http://127.0.0.1:8002/v1/chat/completions \
-H "Content-Type: application/json" \
-N \
-d '{
"messages": [
{"role": "user", "content": "Generate a happy birthday song"}
],
"stream": true
}'
```
### Example 5: Full Control with All Parameters
```bash
curl -X POST http://127.0.0.1:8002/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"role": "user",
"content": "<prompt>Dreamy lo-fi hip hop beat with vinyl crackle</prompt><lyrics>[inst]</lyrics>"
}
],
"temperature": 0.9,
"top_p": 0.95,
"bpm": 85,
"duration": 30,
"instrumental": true,
"thinking": false,
"use_cot_metas": true,
"use_cot_caption": true,
"use_cot_language": false,
"use_format": true
}'
```
---
## Error Codes
| HTTP Status | Description |
|---|---|
| 400 | Invalid request format or missing valid input |
| 401 | Missing or invalid API key |
| 500 | Internal error during music generation |
| 503 | Model not yet initialized |
Error response format:
```json
{
"detail": "Error description message"
}
```
---
## Server Configuration (Environment Variables)
The following environment variables can be used to configure the server (for operations reference):
| Variable | Default | Description |
|---|---|---|
| `OPENROUTER_API_KEY` | None | API authentication key |
| `OPENROUTER_HOST` | `127.0.0.1` | Listen address |
| `OPENROUTER_PORT` | `8002` | Listen port |
| `ACESTEP_CONFIG_PATH` | `acestep-v15-turbo` | DiT model configuration path |
| `ACESTEP_DEVICE` | `auto` | Inference device |
| `ACESTEP_LM_MODEL_PATH` | `acestep-5Hz-lm-0.6B` | LLM model path |
| `ACESTEP_LM_BACKEND` | `vllm` | LLM inference backend |
================================================
FILE: .claude/skills/acestep-docs/getting-started/ABOUT.md
================================================
# ACE-Step Project Overview
> For installation instructions, see [README.md](README.md)
## Links
- [Project Page](https://ace-step.github.io/ace-step-v1.5.github.io/)
- [Hugging Face](https://huggingface.co/ACE-Step/Ace-Step1.5)
- [ModelScope](https://modelscope.cn/models/ACE-Step/Ace-Step1.5)
- [Space Demo](https://huggingface.co/spaces/ACE-Step/Ace-Step-v1.5)
- [Discord](https://discord.gg/PeWDxrkdj7)
- [Technical Report](https://arxiv.org/abs/2602.00744)
## Abstract
ACE-Step v1.5 is a highly efficient open-source music foundation model that brings commercial-grade generation to consumer hardware. Key highlights:
- Quality beyond most commercial music models
- Under 2 seconds per full song on A100, under 10 seconds on RTX 3090
- Runs locally with less than 4GB of VRAM
- Supports lightweight LoRA personalization from just a few songs
The architecture combines a Language Model (LM) as an omni-capable planner with a Diffusion Transformer (DiT). The LM transforms simple user queries into comprehensive song blueprints—scaling from short loops to 10-minute compositions.
## Features
### Performance
- **Ultra-Fast Generation** — Under 2s per full song on A100
- **Flexible Duration** — 10 seconds to 10 minutes (600s)
- **Batch Generation** — Up to 8 songs simultaneously
### Generation Quality
- **Commercial-Grade Output** — Between Suno v4.5 and Suno v5
- **Rich Style Support** — 1000+ instruments and styles
- **Multi-Language Lyrics** — 50+ languages
### Capabilities
| Feature | Description |
|---------|-------------|
| Reference Audio Input | Use reference audio to guide style |
| Cover Generation | Create covers from existing audio |
| Repaint & Edit | Selective local audio editing |
| Track Separation | Separate into individual stems |
| Vocal2BGM | Auto-generate accompaniment |
| Metadata Control | Duration, BPM, key/scale, time signature |
| Simple Mode | Full songs from simple descriptions |
| LoRA Training | 8 songs, 1 hour on 3090 (12GB VRAM) |
## Architecture
The system uses a hybrid LM + DiT architecture:
- **LM (Language Model)**: Plans metadata, lyrics, captions via Chain-of-Thought
- **DiT (Diffusion Transformer)**: Generates audio from the LM's blueprint
## Model Zoo
### DiT Models
| Model | Steps | Quality | Diversity | HuggingFace |
|-------|:-----:|:-------:|:---------:|-------------|
| `acestep-v15-base` | 50 | Medium | High | [Link](https://huggingface.co/ACE-Step/acestep-v15-base) |
| `acestep-v15-sft` | 50 | High | Medium | [Link](https://huggingface.co/ACE-Step/acestep-v15-sft) |
| `acestep-v15-turbo` | 8 | Very High | Medium | [Link](https://huggingface.co/ACE-Step/Ace-Step1.5) |
### LM Models
| Model | Audio Understanding | Composition | HuggingFace |
|-------|:------------------:|:-----------:|-------------|
| `acestep-5Hz-lm-0.6B` | Medium | Medium | [Link](https://huggingface.co/ACE-Step/acestep-5Hz-lm-0.6B) |
| `acestep-5Hz-lm-1.7B` | Medium | Medium | [Link](https://huggingface.co/ACE-Step/Ace-Step1.5) |
| `acestep-5Hz-lm-4B` | Strong | Strong | [Link](https://huggingface.co/ACE-Step/acestep-5Hz-lm-4B) |
## License
This project is licensed under [MIT](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/LICENSE).
## Citation
```BibTeX
@misc{gong2026acestep,
title={ACE-Step 1.5: Pushing the Boundaries of Open-Source Music Generation},
author={Junmin Gong, Yulin Song, Wenxiao Zhao, Sen Wang, Shengyuan Xu, Jing Guo},
howpublished={\url{https://github.com/ace-step/ACE-Step-1.5}},
year={2026}
}
```
================================================
FILE: .claude/skills/acestep-docs/getting-started/README.md
================================================
# ACE-Step Installation Guide
## Requirements
- Python 3.11
- CUDA GPU recommended (works on CPU/MPS/MLX but slower)
## Installation
### Windows Portable Package (Recommended for Windows)
1. Download and extract: [ACE-Step-1.5.7z](https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z)
2. Requirements: CUDA 12.8
3. The package includes `python_embeded` with all dependencies pre-installed
**Quick Start:**
```bash
# Launch Gradio Web UI (CUDA)
start_gradio_ui.bat
# Launch REST API Server (CUDA)
start_api_server.bat
# Launch Gradio Web UI (AMD ROCm)
start_gradio_ui_rocm.bat
# Launch REST API Server (AMD ROCm)
start_api_server_rocm.bat
```
### Launch Scripts (All Platforms)
Ready-to-use launch scripts with auto environment detection, update checking, and uv auto-install.
**Windows (.bat):**
```bash
start_gradio_ui.bat # Gradio Web UI (CUDA)
start_api_server.bat # REST API Server (CUDA)
start_gradio_ui_rocm.bat # Gradio Web UI (AMD ROCm)
start_api_server_rocm.bat # REST API Server (AMD ROCm)
```
**Linux (.sh):**
```bash
chmod +x start_gradio_ui.sh start_api_server.sh # First time only
./start_gradio_ui.sh # Gradio Web UI (CUDA)
./start_api_server.sh # REST API Server (CUDA)
```
**macOS Apple Silicon (.sh):**
```bash
chmod +x start_gradio_ui_macos.sh start_api_server_macos.sh # First time only
./start_gradio_ui_macos.sh # Gradio Web UI (MLX backend)
./start_api_server_macos.sh # REST API Server (MLX backend)
```
All launch scripts support:
- Startup update check (enabled by default, configurable)
- Auto environment detection (`python_embeded` or `uv`)
- Auto install `uv` if needed
- Configurable download source (HuggingFace/ModelScope)
- Customizable language, models, and parameters
See [SCRIPT_CONFIGURATION.md](../guides/SCRIPT_CONFIGURATION.md) for configuration details.
**Manual Launch (Using Python Directly):**
```bash
# Gradio Web UI
python_embeded\python.exe acestep\acestep_v15_pipeline.py # Windows portable
python acestep/acestep_v15_pipeline.py # Linux/macOS
# REST API Server
python_embeded\python.exe acestep\api_server.py # Windows portable
python acestep/api_server.py # Linux/macOS
```
### Standard Installation (All Platforms)
**1. Install uv (Package Manager)**
```bash
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```
**2. Clone & Install**
```bash
git clone https://github.com/ACE-Step/ACE-Step-1.5.git
cd ACE-Step-1.5
uv sync
```
**3. Launch**
**Using uv:**
```bash
# Gradio Web UI (http://localhost:7860)
uv run acestep
# REST API Server (http://localhost:8001)
uv run acestep-api
```
**Using Python directly:**
> **Note:** Make sure to activate your Python environment first:
> - **Conda environment**: Run `conda activate your_env_name` first
> - **venv**: Run `source venv/bin/activate` (Linux/Mac) or `venv\Scripts\activate` (Windows) first
> - **System Python**: Use `python` or `python3` directly
```bash
# Gradio Web UI
python acestep/acestep_v15_pipeline.py
# REST API Server
python acestep/api_server.py
```
## Model Download
Models are automatically downloaded on first run. Manual download options:
### Download Source Configuration
ACE-Step supports multiple download sources:
| Source | Description |
|--------|-------------|
| **auto** (default) | Auto-detect best source based on network |
| **modelscope** | Use ModelScope as download source |
| **huggingface** | Use HuggingFace Hub as download source |
**Using uv:**
```bash
# Download main model
uv run acestep-download
# Download from ModelScope
uv run acestep-download --download-source modelscope
# Download from HuggingFace Hub
uv run acestep-download --download-source huggingface
# Download all models
uv run acestep-download --all
# List available models
uv run acestep-download --list
```
**Using Python directly:**
> **Note:** Replace `python` with your environment's Python executable:
> - Windows portable package: `python_embeded\python.exe`
> - Conda/venv: Activate environment first, then use `python`
> - System: Use `python` or `python3`
```bash
# Download main model
python -m acestep.model_downloader
# Download from ModelScope
python -m acestep.model_downloader --download-source modelscope
# Download from HuggingFace Hub
python -m acestep.model_downloader --download-source huggingface
# Download all models
python -m acestep.model_downloader --all
# List available models
python -m acestep.model_downloader --list
```
### GPU VRAM Recommendations
| GPU VRAM | Recommended LM Model | Notes |
|----------|---------------------|-------|
| ≤6GB | None (DiT only) | LM disabled to save memory |
| 6-12GB | `acestep-5Hz-lm-0.6B` | Lightweight, good balance |
| 12-16GB | `acestep-5Hz-lm-1.7B` | Better quality |
| ≥16GB | `acestep-5Hz-lm-4B` | Best quality |
## Command Line Options
### Gradio UI (`acestep`)
| Option | Default | Description |
|--------|---------|-------------|
| `--port` | 7860 | Server port |
| `--server-name` | 127.0.0.1 | Server address (`0.0.0.0` for network) |
| `--share` | false | Create public Gradio link |
| `--language` | en | UI language: `en`, `zh`, `ja` |
| `--init_service` | false | Auto-initialize models on startup |
| `--config_path` | auto | DiT model name |
| `--lm_model_path` | auto | LM model name |
| `--offload_to_cpu` | auto | CPU offload (auto if VRAM < 16GB) |
| `--download-source` | auto | Model download source: `auto`, `huggingface`, or `modelscope` |
| `--enable-api` | false | Enable REST API endpoints |
| `--api-key` | none | API authentication key |
**Examples:**
> **Note for Python users:** Replace `python` with your environment's Python executable (see note in Launch section above).
```bash
# Public access with Chinese UI
uv run acestep --server-name 0.0.0.0 --share --language zh
# Or using Python directly:
python acestep/acestep_v15_pipeline.py --server-name 0.0.0.0 --share --language zh
# Pre-initialize models
uv run acestep --init_service true --config_path acestep-v15-turbo
# Or using Python directly:
python acestep/acestep_v15_pipeline.py --init_service true --config_path acestep-v15-turbo
# Enable API with authentication
uv run acestep --enable-api --api-key sk-your-secret-key
# Or using Python directly:
python acestep/acestep_v15_pipeline.py --enable-api --api-key sk-your-secret-key
# Use ModelScope as download source
uv run acestep --download-source modelscope
# Or using Python directly:
python acestep/acestep_v15_pipeline.py --download-source modelscope
```
### REST API Server (`acestep-api`)
Same options as Gradio UI. See [API documentation](../api/API.md) for endpoints.
================================================
FILE: .claude/skills/acestep-docs/getting-started/Tutorial.md
================================================
# ACE-Step 1.5 Ultimate Guide (Must Read)
---
Hello everyone, I'm Gong Junmin, the developer of ACE-Step. Through this tutorial, I'll guide you through the design philosophy and usage of ACE-Step 1.5.
## Mental Models
Before we begin, we need to establish the correct mental models to set proper expectations.
### Human-Centered Design
This model is not designed for **one-click generation**, but for **human-centered generation**.
Understanding this distinction is crucial.
### What is One-Click Generation?
You input a prompt, click generate, listen to a few versions, pick one that sounds good, and use it. If someone else inputs the same prompt, they'll likely get similar results.
In this mode, you and AI have a **client-vendor** relationship. You come with a clear purpose, with a vague expectation in mind, hoping AI delivers a product close to that expectation. Essentially, it's not much different from searching on Google or finding songs on Spotify—just with a bit more customization.
AI is a service, not a creative inspirer.
Suno, Udio, MiniMax, Mureka—these platforms are all designed with this philosophy. They can scale up models as services to ensure delivery. Your generated music is bound by their agreements; you can't run it locally, can't fine-tune for personalized exploration; if they secretly change models or terms, you can only accept it.
### What is Human-Centered Generation?
If we weaken the AI layer and strengthen the human layer—letting more human will, creativity, and inspiration give life to AI—this is human-centered generation.
Unlike the strong purposefulness of one-click generation, human-centered generation has more of a **playful** nature. It's more like an interactive game where you and the model are **collaborators**.
The workflow is like this: you throw out some inspiration seeds, get a few songs, choose interesting directions from them to continue iterating—
- Adjust prompts to regenerate
- Use **Cover** to maintain structure and adjust details
- Use **Repaint** for local modifications
- Use **Add Layer** to add or remove instrument layers
At this point, AI is not a servant to you, but an **inspirer**.
### What Conditions Must This Design Meet?
For human-centered generation to truly work, the model must meet several key conditions:
**First, it must be open-source, locally runnable, and trainable.**
This isn't technical purism, but a matter of ownership. When you use closed-source platforms, you don't own the model, and your generated works are bound by their agreements. Version updates, term changes, service shutdowns—none of these are under your control.
But when the model is open-source and locally runnable, everything changes: **You forever own this model, and you forever own all the creations you make with it.** No third-party agreement hassles, no platform risks, you can fine-tune, modify, and build your own creative system based on it. Your works will forever belong to you. It's like buying an instrument—you can use it anytime, anywhere, and adjust it anytime, anywhere.
**Second, it must be fast.**
Human time is precious, but more importantly—**slow generation breaks flow state**.
The core of human-centered workflow is the rapid cycle of "try, listen, adjust." If each generation takes minutes, your inspiration dissipates while waiting, and the "play" experience degrades into the "wait" ordeal.
Therefore, we specifically optimized ACE-Step for this: while ensuring quality, we made generation fast enough to support a smooth human-machine dialogue rhythm.
### Finite Game vs Infinite Game
One-click generation is a **finite game**—clear goals, result-oriented, ends at the finish line. To some extent, it coldly hollows out the music industry, replacing many people's jobs.
Human-centered generation is an **infinite game**—because the fun lies in the process, and the process never ends.
Our vision is to democratize AI music generation. Let ACE-Step become a big toy in your pocket, let music return to **Play** itself—the creative "play," not just clicking play.
---
## The Elephant Rider Metaphor
> Recommended reading: [The Complete Guide to Mastering Suno](https://www.notion.so/The-Complete-Guide-to-Mastering-Suno-Advanced-Strategies-for-Professional-Music-Generation-2d6ae744ebdf8024be42f6645f884221)—this blog tutorial can help you establish the foundational understanding of AI music.
AI music generation is like the famous **elephant rider metaphor** in psychology.
Consciousness rides on the subconscious, humans ride on elephants. You can give directions, but you can't make the elephant precisely and instantly execute every command. It has its own inertia, its own temperament, its own will.
This elephant is the music generation model.
### The Iceberg Model
Between audio and semantics lies a hidden iceberg.
What we can describe with language—style, instruments, timbre, emotion, scenes, progression, lyrics, vocal style—these are familiar words, the parts we can touch. But together, they're still just a tiny tip of the audio iceberg above the water.
What's the most precise control? You input the expected audio, and the model returns it unchanged.
But as long as you're using text descriptions, references, prompts—the model will have room to play. This isn't a bug, it's the nature of things.
### What is the Elephant?
This elephant is a fusion of countless elements: data distribution, model scale, algorithm design, annotation bias, evaluation bias—**it's an abstract crystallization of human music history and engineering trade-offs.**
Any deviation in these elements will cause it to fail to accurately reflect your taste and expectations.
Of course, we can expand data scale, improve algorithm efficiency, increase annotation precision, expand model capacity, introduce more professional evaluation systems—these are all directions we can optimize as model developers.
But even if one day we achieve technical "perfection," there's still a fundamental problem we can't avoid: **taste.**
### Taste and Expectations
Taste varies from person to person.
If a music generation model tries to please all listeners, its output will tend toward the popular average of human music history—**this will be extremely mediocre.**
It's humans who give sound meaning, emotion, experience, life, and cultural symbolic value. It's a small group of artists who create unique tastes, then drive ordinary people to consume and follow, turning niche into mainstream popularity. These pioneering minority artists become legends.
So when you find the model's output "not to your taste," this might not be the model's problem—**but rather your taste happens to be outside that "average."** This is a good thing.
This means: **You need to learn to guide this elephant, not expect it to automatically understand you.**
---
## Knowing the Elephant Herd: Model Architecture and Selection
Now you understand the "elephant" metaphor. But actually—
**This isn't one elephant, but an entire herd—elephants large and small, forming a family.** 🐘🐘🐘🐘
### Architecture Principles: Two Brains
ACE-Step 1.5 uses a **hybrid architecture** with two core components working together:
```
User Input → [5Hz LM] → Semantic Blueprint → [DiT] → Audio
↓
Metadata Inference
Caption Optimization
Structure Planning
```
**5Hz LM (Language Model) — Planner (Optional)**
The LM is an "omni-capable planner" responsible for understanding your intent and making plans:
- Infers music metadata (BPM, key, duration, etc.) through **Chain-of-Thought**
- Optimizes and expands your caption—understanding and supplementing your intent
- Generates **semantic codes**—implicitly containing composition melody, orchestration, and some timbre information
The LM learns **world knowledge** from training data. It's a planner that improves usability and helps you quickly generate prototypes.
**But the LM is not required.**
If you're very clear about what you want, or already have a clear planning goal—you can completely skip the LM planning step by not using `thinking` mode.
For example, in **Cover mode**, you use reference audio to constrain composition, chords, and structure, letting DiT generate directly. Here, **you replace the LM's work**—you become the planner yourself.
Another example: in **Repaint mode**, you use reference audio as context, constraining timbre, mixing, and details, letting DiT directly adjust locally. Here, DiT is more like your creative brainstorming partner, helping with creative ideation and fixing local disharmony.
**DiT (Diffusion Transformer) — Executor**
DiT is the "audio craftsman," responsible for turning plans into reality:
- Receives semantic codes and conditions generated by LM
- Gradually "carves" audio from noise through the **diffusion process**
- Decides final timbre, mixing, details
**Why this design?**
Traditional methods let diffusion models generate audio directly from text, but text-to-audio mapping is too vague. ACE-Step introduces LM as an intermediate layer:
- LM excels at understanding semantics and planning
- DiT excels at generating high-fidelity audio
- They work together, each doing their part
### Choosing the Planner: LM Models
LM has four options: **No LM** (disable thinking mode), **0.6B**, **1.7B**, **4B**.
Their training data is completely identical; the difference is purely in **knowledge capacity**:
- Larger models have richer world knowledge
- Larger models have stronger memory (e.g., remembering reference audio melodies)
- Larger models perform relatively better on long-tail styles or instruments
| Choice | Speed | World Knowledge | Memory | Use Cases |
|--------|:-----:|:---------------:|:------:|-----------|
| No LM | ⚡⚡⚡⚡ | — | — | You do the planning (e.g., Cover mode) |
| `0.6B` | ⚡⚡⚡ | Basic | Weak | Low VRAM (< 8GB), rapid prototyping |
| `1.7B` | ⚡⚡ | Medium | Medium | **Default recommendation** |
| `4B` | ⚡ | Rich | Strong | Complex tasks, high-quality generation |
**How to choose?**
Based on your hardware:
- **VRAM < 8GB** → No LM or `0.6B`
- **VRAM 8–16GB** → `1.7B` (default)
- **VRAM > 16GB** → `1.7B` or `4B`
### Choosing the Executor: DiT Models
With a planning scheme, you still need to choose an executor. DiT is the core of ACE-Step 1.5—it handles various tasks and decides how to interpret LM-generated codes.
We've open-sourced **4 Turbo models**, **1 SFT model**, and **1 Base model**.
#### Turbo Series (Recommended for Daily Use)
Turbo models are trained with distillation, generating high-quality audio in just 8 steps. The core difference between the four variants is the **shift hyperparameter configuration during distillation**.
**What is shift?**
Shift determines the "attention allocation" during DiT denoising:
- **Larger shift** → More effort spent on early denoising (building large structure from pure noise), **stronger semantics**, clearer overall framework
- **Smaller shift** → More even step distribution, **more details**, but details might also be noise
Simple understanding: high shift is like "draw outline first then fill details," low shift is like "draw and fix simultaneously."
| Model | Distillation Config | Characteristics |
|-------|---------------------|-----------------|
| `turbo` (default) | Joint distillation on shift 1, 2, 3 | **Best balance of creativity and semantics**, thoroughly tested, recommended first choice |
| `turbo-shift1` | Distilled only on shift=1 | Richer details, but semantics weaker |
| `turbo-shift3` | Distilled only on shift=3 | Clearer, richer timbre, but may sound "dry," minimal orchestration |
| `turbo-continuous` | Experimental, supports continuous shift 1–5 | Most flexible tuning, but not thoroughly tested |
You can choose based on target music style—you might find you prefer a certain variant. **We recommend starting with default turbo**—it's the most balanced and proven choice.
#### SFT Model
Compared to Turbo, SFT model has two notable features:
- **Supports CFG** (Classifier-Free Guidance), allowing fine-tuning of prompt adherence
- **More steps** (50 steps), giving the model more time to "think"
The cost: more steps mean error accumulation, audio clarity may be slightly inferior to Turbo. But its **detail expression and semantic parsing will be better**.
If you don't care about inference time, like tuning CFG and steps, and prefer that rich detail feel—SFT is a good choice. LM-generated codes can also work with SFT models.
#### Base Model
Base is the **master of all tasks**, with three exclusive tasks beyond SFT and Turbo:
| Task | Description |
|------|-------------|
| `extract` | Extract single tracks from mixed audio (e.g., separate vocals) |
| `lego` | Add new tracks to existing tracks (e.g., add drums to guitar) |
| `complete` | Add mixed accompaniment to single track (e.g., add guitar+drums accompaniment to vocals) |
Additionally, Base has the **strongest plasticity**. If you have large-scale fine-tuning needs, we recommend starting experiments with Base to train your own SFT model.
#### Creating Your Custom Model
Beyond official models, you can also use **LoRA fine-tuning** to create your custom model.
We'll release an example LoRA model—trained on 20+ "Happy New Year" themed songs, specifically suited for expressing festive atmosphere. This is just a starting point.
**What does a custom model mean?**
You can reshape DiT's capabilities and preferences with your own data recipe:
- Like a specific timbre style? Train with that type of songs
- Want the model better at a certain genre? Collect related data for fine-tuning
- Have your own unique aesthetic taste? "Teach" it to the model
This greatly expands **customization and playability**—train a model unique to you with your aesthetic taste.
> For detailed LoRA training guide, see the "LoRA Training" tab in Gradio UI.
#### DiT Selection Summary
| Model | Steps | CFG | Speed | Exclusive Tasks | Recommended Scenarios |
|-------|:-----:|:---:|:-----:|-----------------|----------------------|
| `turbo` (default) | 8 | ❌ | ⚡⚡⚡ | — | Daily use, rapid iteration |
| `sft` | 50 | ✅ | ⚡ | — | Pursuing details, like tuning |
| `base` | 50 | ✅ | ⚡ | extract, lego, complete | Special tasks, large-scale fine-tuning |
### Combination Strategies
Default configuration is **turbo + 1.7B LM**, suitable for most scenarios.
| Need | Recommended Combination |
|------|------------------------|
| Fastest speed | `turbo` + No LM or `0.6B` |
| Daily use | `turbo` + `1.7B` (default) |
| Pursuing details | `sft` + `1.7B` or `4B` |
| Special tasks | `base` |
| Large-scale fine-tuning | `base` |
| Low VRAM (< 4GB) | `turbo` + No LM + CPU offload |
### Downloading Models
```bash
# Download default models (turbo + 1.7B LM)
uv run acestep-download
# Download all models
uv run acestep-download --all
# Download specific model
uv run acestep-download --model acestep-v15-base
uv run acestep-download --model acestep-5Hz-lm-0.6B
# List available models
uv run acestep-download --list
```
You need to download models into a `checkpoints` folder for easy identification.
---
## Guiding the Elephant: What Can You Control?
Now that you know this herd of elephants, let's learn how to communicate with them.
Each generation is determined by three types of factors: **input control**, **inference hyperparameters**, and **random factors**.
### I. Input Control: What Do You Want?
This is the part where you communicate "creative intent" with the model—what kind of music you want to generate.
| Category | Parameter | Function |
|----------|-----------|----------|
| **Task Type** | `task_type` | Determines generation mode: text2music, cover, repaint, lego, extract, complete |
| **Text Input** | `caption` | Description of overall music elements: style, instruments, emotion, atmosphere, timbre, vocal gender, progression, etc. |
| | `lyrics` | Temporal element description: lyric content, music structure evolution, vocal changes, vocal/instrument performance style, start/end style, articulation, etc. (use `[Instrumental]` for instrumental music) |
| **Music Metadata** | `bpm` | Tempo (30–300) |
| | `keyscale` | Key (e.g., C Major, Am) |
| | `timesignature` | Time signature (4/4, 3/4, 6/8) |
| | `vocal_language` | Vocal language |
| | `duration` | Target duration (seconds) |
| **Audio Reference** | `reference_audio` | Global reference for timbre or style (for cover, style transfer) |
| | `src_audio` | Source audio for non-text2music tasks (text2music defaults to silence, no input needed) |
| | `audio_codes` | Semantic codes input to model in Cover mode (advanced: reuse codes for variants, convert songs to codes for extension, combine like DJ mixing) |
| **Interval Control** | `repainting_start/end` | Time interval for operations (repaint redraw area / lego new track area) |
---
#### About Caption: The Most Important Input
**Caption is the most important factor affecting generated music.**
It supports multiple input formats: simple style words, comma-separated tags, complex natural language descriptions. We've trained to be compatible with various formats, ensuring text format doesn't significantly affect model performance.
**We provide at least 5 ways to help you write good captions:**
1. **Random Dice** — Click the random button in the UI to see how example captions are written. You can use this standardized caption as a template and have an LLM rewrite it to your desired form.
2. **Format Auto-Rewrite** — We support using the `format` feature to automatically expand your handwritten simple caption into complex descriptions.
3. **CoT Rewrite** — If LM is initialized, whether `thinking` mode is enabled or not, we support rewriting and expanding captions through Chain-of-Thought (unless you actively disable it in settings, or LM is not initialized).
4. **Audio to Caption** — Our LM supports converting your input audio to caption. While precision is limited, the vague direction is correct—enough as a starting point.
5. **Simple Mode** — Just input a simple song description, and LM will automatically generate complete caption, lyrics, and metas samples—suitable for quick starts.
Regardless of which method, they all solve a real problem: **As ordinary people, our music vocabulary is impoverished.**
If you want generated music to be more interesting and meet expectations, **Prompting is always the optimal option**—it brings the highest marginal returns and surprises.
**Common Dimensions for Caption Writing:**
| Dimension | Examples |
|-----------|----------|
| **Style/Genre** | pop, rock, jazz, electronic, hip-hop, R&B, folk, classical, lo-fi, synthwave |
| **Emotion/Atmosphere** | melancholic, uplifting, energetic, dreamy, dark, nostalgic, euphoric, intimate |
| **Instruments** | acoustic guitar, piano, synth pads, 808 drums, strings, brass, electric bass |
| **Timbre Texture** | warm, bright, crisp, muddy, airy, punchy, lush, raw, polished |
| **Era Reference** | 80s synth-pop, 90s grunge, 2010s EDM, vintage soul, modern trap |
| **Production Style** | lo-fi, high-fidelity, live recording, studio-polished, bedroom pop |
| **Vocal Characteristics** | female vocal, male vocal, breathy, powerful, falsetto, raspy, choir |
| **Speed/Rhythm** | slow tempo, mid-tempo, fast-paced, groovy, driving, laid-back |
| **Structure Hints** | building intro, catchy chorus, dramatic bridge, fade-out ending |
**Some Practical Principles:**
1. **Specific beats vague** — "sad piano ballad with female breathy vocal" works better than "a sad song."
2. **Combine multiple dimensions** — Single-dimension descriptions give the model too much room to play; combining style+emotion+instruments+timbre can more precisely anchor your desired direction.
3. **Use references well** — "in the style of 80s synthwave" or "reminiscent of Bon Iver" can quickly convey complex aesthetic preferences.
4. **Texture words are useful** — Adjectives like warm, crisp, airy, punchy can influence mixing and timbre tendencies.
5. **Don't pursue perfect descriptions** — Caption is a starting point, not an endpoint. Write a general direction first, then iterate based on results.
6. **Description granularity determines freedom** — More omitted descriptions give the model more room to play, more random factor influence; more detailed descriptions constrain the model more. Decide specificity based on your needs—want surprises? Write less. Want control? Write more details.
7. **Avoid conflicting words** — Conflicting style combinations easily lead to degraded output. For example, wanting both "classical strings" and "hardcore metal" simultaneously—the model will try to fuse but usually not ideal. Especially when `thinking` mode is enabled, LM has weaker caption generalization than DiT. When prompting is unreasonable, the chance of pleasant surprises is smaller.
**Ways to resolve conflicts:**
- **Repetition reinforcement** — Strengthen the elements you want more in mixed styles by repeating certain words
- **Conflict to evolution** — Transform style conflicts into temporal style evolution. For example: "Start with soft strings, middle becomes noisy dynamic metal rock, end turns to hip-hop"—this gives the model clear guidance on how to handle different styles, rather than mixing them into a mess
> For more prompting tips, see: [The Complete Guide to Mastering Suno](https://www.notion.so/The-Complete-Guide-to-Mastering-Suno-Advanced-Strategies-for-Professional-Music-Generation-2d6ae744ebdf8024be42f6645f884221)—although it's a Suno tutorial, prompting ideas are universal.
---
#### About Lyrics: The Temporal Script
If Caption describes the music's "overall portrait"—style, atmosphere, timbre—then **Lyrics is the music's "temporal script"**, controlling how music unfolds over time.
Lyrics is not just lyric content. It carries:
- The lyric text itself
- **Structure tags** ([Verse], [Chorus], [Bridge]...)
- **Vocal style hints** ([raspy vocal], [whispered]...)
- **Instrumental sections** ([guitar solo], [drum break]...)
- **Energy changes** ([building energy], [explosive drop]...)
**Structure Tags are Key**
Structure tags (Meta Tags) are the most powerful tool in Lyrics. They tell the model: "What is this section, how should it be performed?"
**Common Structure Tags:**
| Category | Tag | Description |
|----------|-----|-------------|
| **Basic Structure** | `[Intro]` | Opening, establish atmosphere |
| | `[Verse]` / `[Verse 1]` | Verse, narrative progression |
| | `[Pre-Chorus]` | Pre-chorus, build energy |
| | `[Chorus]` | Chorus, emotional climax |
| | `[Bridge]` | Bridge, transition or elevation |
| | `[Outro]` | Ending, conclusion |
| **Dynamic Sections** | `[Build]` | Energy gradually rising |
| | `[Drop]` | Electronic music energy release |
| | `[Breakdown]` | Reduced instrumentation, space |
| **Instrumental Sections** | `[Instrumental]` | Pure instrumental, no vocals |
| | `[Guitar Solo]` | Guitar solo |
| | `[Piano Interlude]` | Piano interlude |
| **Special Tags** | `[Fade Out]` | Fade out ending |
| | `[Silence]` | Silence |
**Combining Tags: Use Moderately**
Structure tags can be combined with `-` for finer control:
```
[Chorus - anthemic]
This is the chorus lyrics
Dreams are burning
[Bridge - whispered]
Whisper those words softly
```
This works better than writing `[Chorus]` alone—you're telling the model both what this section is (Chorus) and how to sing it (anthemic).
**⚠️ Note: Don't stack too many tags.**
```
❌ Not recommended:
[Chorus - anthemic - stacked harmonies - high energy - powerful - epic]
✅ Recommended:
[Chorus - anthemic]
```
Stacking too many tags has two risks:
1. The model might mistake tag content as lyrics to sing
2. Too many instructions confuse the model, making effects worse
**Principle**: Keep structure tags concise; put complex style descriptions in Caption.
**⚠️ Key: Maintain Consistency Between Caption and Lyrics**
**Models are not good at resolving conflicts.** If descriptions in Caption and Lyrics contradict, the model gets confused and output quality decreases.
```
❌ Conflict example:
Caption: "violin solo, classical, intimate chamber music"
Lyrics: [Guitar Solo - electric - distorted]
✅ Consistent example:
Caption: "violin solo, classical, intimate chamber music"
Lyrics: [Violin Solo - expressive]
```
**Checklist:**
- Instruments in Caption ↔ Instrumental section tags in Lyrics
- Emotion in Caption ↔ Energy tags in Lyrics
- Vocal description in Caption ↔ Vocal control tags in Lyrics
Think of Caption as "overall setting" and Lyrics as "shot script"—they should tell the same story.
**Vocal Control Tags:**
| Tag | Effect |
|-----|--------|
| `[raspy vocal]` | Raspy, textured vocals |
| `[whispered]` | Whispered |
| `[falsetto]` | Falsetto |
| `[powerful belting]` | Powerful, high-pitched singing |
| `[spoken word]` | Rap/recitation |
| `[harmonies]` | Layered harmonies |
| `[call and response]` | Call and response |
| `[ad-lib]` | Improvised embellishments |
**Energy and Emotion Tags:**
| Tag | Effect |
|-----|--------|
| `[high energy]` | High energy, passionate |
| `[low energy]` | Low energy, restrained |
| `[building energy]` | Increasing energy |
| `[explosive]` | Explosive energy |
| `[melancholic]` | Melancholic |
| `[euphoric]` | Euphoric |
| `[dreamy]` | Dreamy |
| `[aggressive]` | Aggressive |
**Lyric Text Writing Tips**
**1. Control Syllable Count**
**6-10 syllables per line** usually works best. The model aligns syllables to beats—if one line has 6 syllables and the next has 14, rhythm becomes strange.
```
❌ Bad example:
我站在窗前看着外面的世界一切都在改变(18 syllables)
你好(2 syllables)
✅ Good example:
我站在窗前(5 syllables)
看着外面世界(6 syllables)
一切都在改变(6 syllables)
```
**Tip**: Keep similar syllable counts for lines in the same position (e.g., first line of each verse) (±1-2 deviation).
**2. Use Case to Control Intensity**
Uppercase indicates stronger vocal intensity:
```
[Verse]
walking through the empty streets (normal intensity)
[Chorus]
WE ARE THE CHAMPIONS! (high intensity, shouting)
```
**3. Use Parentheses for Background Vocals**
```
[Chorus]
We rise together (together)
Into the light (into the light)
```
Content in parentheses is processed as background vocals or harmonies.
**4. Extend Vowels**
You can extend sounds by repeating vowels:
```
Feeeling so aliiive
```
But use cautiously—effects are unstable, sometimes ignored or mispronounced.
**5. Clear Section Separation**
Separate each section with blank lines:
```
[Verse 1]
First verse lyrics
Continue first verse
[Chorus]
Chorus lyrics
Chorus continues
```
**Avoiding "AI-flavored" Lyrics**
These characteristics make lyrics seem mechanical and lack human touch:
| Red Flag 🚩 | Description |
|-------------|-------------|
| **Adjective stacking** | "neon skies, electric hearts, endless dreams"—filling a section with vague imagery |
| **Rhyme chaos** | Inconsistent rhyme patterns, or forced rhymes causing semantic breaks |
| **Blurred section boundaries** | Lyric content crosses structure tags, Verse content "flows" into Chorus |
| **No breathing room** | Each line too long, can't sing in one breath |
| **Mixed metaphors** | First verse uses water imagery, second suddenly becomes fire, third is flying—listeners can't anchor |
**Metaphor discipline**: Stick to one core metaphor per song, exploring its multiple aspects. For example, choosing "water" as metaphor, you can explore: how love flows around obstacles like water, can be gentle rain or flood, reflects the other's image, can't be grasped but exists. One image, multiple facets—this gives lyrics cohesion.
**Writing Instrumental Music**
If generating pure instrumental music without vocals:
```
[Instrumental]
```
Or use structure tags to describe instrumental development:
```
[Intro - ambient]
[Main Theme - piano]
[Climax - powerful]
[Outro - fade out]
```
**Complete Example**
Assuming Caption is: `female vocal, piano ballad, emotional, intimate atmosphere, strings, building to powerful chorus`
```
[Intro - piano]
[Verse 1]
月光洒在窗台上
我听见你的呼吸
城市在远处沉睡
只有我们还醒着
[Pre-Chorus]
这一刻如此安静
却藏着汹涌的心
[Chorus - powerful]
让我们燃烧吧
像夜空中的烟火
短暂却绚烂
这就是我们的时刻
[Verse 2]
时间在指尖流过
我们抓不住什么
但至少此刻拥有
彼此眼中的火焰
[Bridge - whispered]
如果明天一切消散
至少我们曾经闪耀
[Final Chorus]
让我们燃烧吧
像夜空中的烟火
短暂却绚烂
THIS IS OUR MOMENT!
[Outro - fade out]
```
Note: In this example, Lyrics tags (piano, powerful, whispered) are consistent with Caption descriptions (piano ballad, building to powerful chorus, intimate), with no conflicts.
---
#### About Music Metadata: Optional Fine Control
**Most of the time, you don't need to manually set metadata.**
When you enable `thinking` mode (or enable `use_cot_metas`), LM automatically infers appropriate BPM, key, time signature, etc. based on your Caption and Lyrics. This is usually good enough.
But if you have clear ideas, you can also manually control them:
| Parameter | Control Range | Description |
|-----------|--------------|-------------|
| `bpm` | 30–300 | Tempo. Common distribution: slow songs 60–80, mid-tempo 90–120, fast songs 130–180 |
| `keyscale` | Key | e.g., `C Major`, `Am`, `F# Minor`. Affects overall pitch and emotional color |
| `timesignature` | Time signature | `4/4` (most common), `3/4` (waltz), `6/8` (swing feel) |
| `vocal_language` | Language | Vocal language. LM usually auto-detects from lyrics |
| `duration` | Seconds | Target duration. Actual generation may vary slightly |
**Understanding Control Boundaries**
These parameters are **guidance** rather than **precise commands**:
- **BPM**: Common range (60–180) works well; extreme values (like 30 or 280) have less training data, may be unstable
- **Key**: Common keys (C, G, D, Am, Em) are stable; rare keys may be ignored or shifted
- **Time signature**: `4/4` is most reliable; `3/4`, `6/8` usually OK; complex signatures (like `5/4`, `7/8`) are advanced, effects vary by style
- **Duration**: Short songs (30–60s) and medium length (2–4min) are stable; very long generation may have repetition or structure issues
**The Model's "Reference" Approach**
The model doesn't mechanically execute `bpm=120`, but rather:
1. Uses `120 BPM` as an **anchor point**
2. Samples from distribution near this anchor
3. Final result might be 118 or 122, not exactly 120
It's like telling a musician "around 120 tempo"—they'll naturally play in this range, not rigidly follow a metronome.
**When Do You Need Manual Settings?**
| Scenario | Suggestion |
|----------|------------|
| Daily generation | Don't worry, let LM auto-infer |
| Clear tempo requirement | Manually set `bpm` |
| Specific style (e.g., waltz) | Manually set `timesignature=3/4` |
| Need to match other material | Manually set `bpm` and `duration` |
| Pursue specific key color | Manually set `keyscale` |
**Tip**: If you manually set metadata but generation results clearly don't match—check if there's conflict with Caption/Lyrics. For example, Caption says "slow ballad" but `bpm=160`, the model gets confused.
**Recommended Practice**: Don't write tempo, BPM, key, and other metadata information in Caption. These should be set through dedicated metadata parameters (`bpm`, `keyscale`, `timesignature`, etc.), not described in Caption. Caption should focus on style, emotion, instruments, timbre, and other musical characteristics, while metadata information is handled by corresponding parameters.
---
#### About Audio Control: Controlling Sound with Sound
**Text is dimensionally reduced abstraction; the best control is still controlling with audio.**
There are three ways to control generation with audio, each with different control ranges and uses:
---
##### 1. Reference Audio: Global Acoustic Feature Control
Reference audio (`reference_audio`) is used to control the **acoustic features** of generated music—timbre, mixing style, performance style, etc. It **averages temporal dimension information** and acts **globally**.
**What Does Reference Audio Control?**
Reference audio mainly controls the **acoustic features** of generated music, including:
- **Timbre texture**: Vocal timbre, instrument timbre
- **Mixing style**: Spatial sense, dynamic range, frequency distribution
- **Performance style**: Vocal techniques, playing techniques, expression
- **Overall atmosphere**: The "feeling" conveyed through reference audio
**How Does the Backend Process Reference Audio?**
When you provide reference audio, the system performs the following processing:
1. **Audio Preprocessing**:
- Load audio file, normalize to **stereo 48kHz** format
- Detect silence, ignore if audio is completely silent
- If audio length is less than 30 seconds, repeat to fill to at least 30 seconds
- Randomly select 10-second segments from front, middle, and back positions, concatenate into 30-second reference segment
2. **Encoding Conversion**:
- Use **VAE (Variational Autoencoder)** `tiled_encode` method to encode audio into **latent representation (latents)**
- These latents contain acoustic feature information but remove specific melody, rhythm, and other structural information
- Encoded latents are input as conditions to DiT generation process, **averaging temporal dimension information, acting globally on entire generation process**
---
##### 2. Source Audio: Semantic Structure Control
Source audio (`src_audio`) is used for **Cover tasks**, performing **melodic structure control**. Its principle is to quantize your input source audio into semantically structured information.
**What Does Source Audio Control?**
Source audio is converted into **semantically structured information**, including:
- **Melody**: Note direction and pitch
- **Rhythm**: Beat, accent, groove
- **Chords**: Harmonic progression and changes
- **Orchestration**: Instrument arrangement and layers
- **Some timbre**: Partial timbre information
**What Can You Do With It?**
1. **Control style**: Maintain source audio structure, change style and details
2. **Transfer style**: Apply source audio structure to different styles
3. **Retake lottery**: Generate similar structure but different variants, get different interpretations through multiple generations
4. **Control influence degree**: Control source audio influence strength through `audio_cover_strength` parameter (0.0–1.0)
- Higher strength: generation results more strictly follow source audio structure
- Lower strength: generation results have more room for free play
**Advanced Cover Usage**
You can use Cover to **Remix a song**, and it supports changing Caption and Lyrics:
- **Remix creation**: Input a song as source audio, reinterpret it by modifying Caption and Lyrics
- Change style: Use different Caption descriptions (e.g., change from pop to rock)
- Change lyrics: Rewrite lyrics with new Lyrics, maintaining original melody structure
- Change emotion: Adjust overall atmosphere through Caption (e.g., change from sad to joyful)
- **Build complex music structures**: Build complex melodic direction, layers, and groove based on your needed structure influence degree
- Fine-tune structure adherence through `audio_cover_strength`
- Combine Caption and Lyrics modifications to create new expression while maintaining core structure
- Can generate multiple versions, each with different emphasis on structure, style, lyrics
---
##### 3. Source Audio Context-Based Control: Local Completion and Modification
This is the **Repaint task**, performing completion or modification based on source audio context.
**Repaint Principle**
Repaint is based on **context completion** principle:
- Can complete **beginning**, **middle local**, **ending**, or **any region**
- Operation range: **3 seconds to 90 seconds**
- Model references source audio context information, generating within specified interval
**What Can You Do With It?**
1. **Local modification**: Modify lyrics, structure, or content in specified interval
2. **Change lyrics**: Maintain melody and orchestration, only change lyric content
3. **Change structure**: Change music structure in specified interval (e.g., change Verse to Chorus)
4. **Continue writing**: Continue writing beginning or ending based on context
5. **Clone timbre**: Clone source audio timbre characteristics based on context
**Advanced Repaint Usage**
You can use Repaint for more complex creative needs:
- **Infinite duration generation**:
- Through multiple Repaint operations, can continuously extend audio, achieving infinite duration generation
- Each continuation is based on previous segment's context, maintaining natural transitions and coherence
- Can generate in segments, each 3–90 seconds, finally concatenate into complete work
- **Intelligent audio stitching**:
- Intelligently organize and stitch two audios together
- Use Repaint at first audio's end to continue, making transitions naturally connect
- Or use Repaint to modify connection part between two audios for smooth transitions
- Model automatically handles rhythm, harmony, timbre connections based on context, making stitched audio sound like a complete work
---
##### 4. Base Model Advanced Audio Control Tasks
In the **Base model**, we also support more advanced audio control tasks:
**Lego Task**: Intelligently add new tracks based on existing tracks
- Input an existing audio track (e.g., vocals)
- Model intelligently adds new tracks (e.g., drums, guitar, bass, etc.)
- New tracks coordinate with original tracks in rhythm and harmony
**Complete Task**: Add mixed tracks to single track
- Input a single-track audio (e.g., a cappella vocals)
- Model generates complete mixed accompaniment tracks
- Generated accompaniment matches vocals in style, rhythm, and harmony
**These advanced context completion tasks** greatly expand control methods, more intelligently providing inspiration and creativity.
---
The combination of these parameters determines what you "want." We'll explain input control **principles** and **techniques** in detail later.
### II. Inference Hyperparameters: How Does the Model Generate?
This is the part that affects "generation process behavior"—doesn't change what you want, but changes how the model does it.
**DiT (Diffusion Model) Hyperparameters:**
| Parameter | Function | Default | Tuning Advice |
|-----------|----------|---------|---------------|
| `inference_steps` | Diffusion steps | 8 (turbo) | More steps = finer but slower. Turbo uses 8, Base uses 32–100 |
| `guidance_scale` | CFG strength | 7.0 | Higher = more prompt adherence, but may overfit. Only Base model effective |
| `use_adg` | Adaptive Dual Guidance | False | After enabling, dynamically adjusts CFG, Base model only |
| `cfg_interval_start/end` | CFG effective interval | 0.0–1.0 | Controls which stage to apply CFG |
| `shift` | Timestep offset | 1.0 | Adjusts denoising trajectory, affects generation style |
| `infer_method` | Inference method | "ode" | `ode` deterministic, `sde` introduces randomness |
| `timesteps` | Custom timesteps | None | Advanced usage, overrides steps and shift |
| `audio_cover_strength` | Reference audio/codes influence strength | 1.0 | 0.0–1.0, higher = closer to reference, lower = more freedom |
**5Hz LM (Language Model) Hyperparameters:**
| Parameter | Function | Default | Tuning Advice |
|-----------|----------|---------|---------------|
| `thinking` | Enable CoT reasoning | True | Enable to let LM reason metadata and codes |
| `lm_temperature` | Sampling temperature | 0.85 | Higher = more random/creative, lower = more conservative/deterministic |
| `lm_cfg_scale` | LM CFG strength | 2.0 | Higher = more positive prompt adherence |
| `lm_top_k` | Top-K sampling | 0 | 0 means disabled, limits candidate word count |
| `lm_top_p` | Top-P sampling | 0.9 | Nucleus sampling, limits cumulative probability |
| `lm_negative_prompt` | Negative prompt | "NO USER INPUT" | Tells LM what not to generate |
| `use_cot_metas` | CoT reason metadata | True | Let LM auto-infer BPM, key, etc. |
| `use_cot_caption` | CoT rewrite caption | True | Let LM optimize your description |
| `use_cot_language` | CoT detect language | True | Let LM auto-detect vocal language |
| `use_constrained_decoding` | Constrained decoding | True | Ensures correct output format |
The combination of these parameters determines how the model "does it."
**About Parameter Tuning**
It's important to emphasize that **tuning factors and random factors sometimes have comparable influence**. When you adjust a parameter, it may be hard to tell if it's the parameter's effect or randomness causing the change.
Therefore, **we recommend fixing random factors when tuning**—by setting a fixed `seed` value, ensuring each generation starts from the same initial noise, so you can accurately feel the parameter's real impact on generated audio. Otherwise, parameter change effects may be masked by randomness, causing you to misjudge the parameter's role.
### III. Random Factors: Sources of Uncertainty
Even with identical inputs and hyperparameters, two generations may produce different results. This is because:
**1. DiT's Initial Noise**
- Diffusion models start from random noise and gradually denoise
- `seed` parameter controls this initial noise
- Different seed → different starting point → different endpoint
**2. LM's Sampling Randomness**
- When `lm_temperature > 0`, the sampling process itself has randomness
- Same prompt, each sampling may choose different tokens
**3. Additional Noise When `infer_method = "sde"`**
- SDE method injects additional randomness during denoising
---
#### Pros and Cons of Random Factors
Randomness is a double-edged sword.
**Benefits of Randomness:**
- **Explore creative space**: Same input can produce different variants, giving you more choices
- **Discover unexpected surprises**: Sometimes randomness brings excellent results you didn't expect
- **Avoid repetition**: Each generation is different, won't fall into single-pattern loops
**Challenges of Randomness:**
- **Uncontrollable results**: You can't precisely predict generation results, may generate multiple times without satisfaction
- **Hard to reproduce**: Even with identical inputs, hard to reproduce a specific good result
- **Tuning difficulty**: When adjusting parameters, hard to tell if it's parameter effect or randomness change
- **Screening cost**: Need to generate multiple versions to find satisfactory ones, increasing time cost
#### What Mindset to Face Random Factors?
**1. Accept Uncertainty**
- Randomness is an essential characteristic of AI music generation, not a bug, but a feature
- Don't expect every generation to be perfect; treat randomness as an exploration tool
**2. Embrace the Exploration Process**
- Treat generation process as "gacha" or "treasure hunting"—try multiple times, always find surprises
- Enjoy discovering unexpectedly good results, rather than obsessing over one-time success
**3. Use Fixed Seed Wisely**
- When you want to **understand parameter effects**, fix `seed` to eliminate randomness interference
- When you want to **explore creative space**, let `seed` vary randomly
**4. Batch Generation + Intelligent Screening**
- Don't rely on single generation; batch generate multiple versions
- Use automatic scoring mechanisms for initial screening to improve efficiency
#### Our Solution: Large Batch + Automatic Scoring
Because our inference is extremely fast, if your GPU VRAM is sufficient, you can explore random space through **large batch**:
- **Batch generation**: Generate multiple versions at once (e.g., batch_size=2,4,8), quickly explore random space
- **Automatic scoring mechanism**: We provide automatic scoring mechanisms that can help you initially screen, doing **test time scaling**
**Automatic Scoring Mechanism**
We provide multiple scoring metrics, among which **my favorite is DiT Lyrics Alignment Score**:
- **DiT Lyrics Alignment Score**: This score implicitly affects lyric accuracy
- It evaluates the alignment degree between lyrics and audio in generated audio
- Higher score means lyrics are more accurately positioned in audio, better match between singing and lyrics
- This is particularly important for music generation with lyrics, can help you screen versions with higher lyric accuracy
- **Other scoring metrics**: Also include other quality assessment metrics, can evaluate generation results from multiple dimensions
**Recommended Workflow:**
1. **Batch generation**: Set larger `batch_size` (e.g., 2, 4, 8), generate multiple versions at once
2. **Enable AutoGen**: Enable automatic generation, let system continuously generate new batches in background
- **AutoGen mechanism**: AutoGen automatically uses same parameters (but random seed) to generate next batch in background while you're viewing current batch results
- This lets you continuously explore random space without manually clicking generate button
- Each new batch uses new random seed, ensuring result diversity
3. **Automatic scoring**: Enable automatic scoring, let system automatically score each version
4. **Initial screening**: Screen versions with higher scores based on DiT Lyrics Alignment Score and other metrics
5. **Manual selection**: Manually select the final version that best meets your needs from screened versions
This fully utilizes randomness to explore creative space while improving efficiency through automation tools, avoiding blind searching in large generation results. AutoGen lets you "generate while listening"—while browsing current results, the next batch is already prepared in the background.
---
## Conclusion
This tutorial currently covers ACE-Step 1.5's core concepts and usage methods:
- **Mental Models**: Understanding human-centered generation design philosophy
- **Model Architecture**: Understanding how LM and DiT work together
- **Input Control**: Mastering text (Caption, Lyrics, metadata) and audio (reference audio, source audio) control methods
- **Inference Hyperparameters**: Understanding parameters affecting generation process
- **Random Factors**: Learning to use randomness to explore creative space, improving efficiency through Large Batch + AutoGen + Automatic Scoring
This is just the beginning. There's much more content we want to share with you:
- More Prompting tips and practical cases
- Detailed usage guides for different task types
- Advanced techniques and creative workflows
- Common issues and solutions
- Performance optimization suggestions
**This tutorial will continue to be updated and improved.** If you have any questions or suggestions during use, feedback is welcome. Let's make ACE-Step your creative partner in your pocket together.
---
*To be continued...*
================================================
FILE: .claude/skills/acestep-docs/guides/ENVIRONMENT_SETUP.md
================================================
# Environment Setup Guide
This guide covers Python environment setup for ACE-Step on Windows, Linux, and macOS.
## Environment Options
### Windows
**Option 1: python_embeded (Portable Package)**
- **Best for**: New users, zero-configuration setup
- **Pros**: Extract and run, no installation required
- **Cons**: Large download size (~7GB)
- **Location**: `python_embeded\python.exe`
- **Download**: https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z
**Option 2: uv (Package Manager)**
- **Best for**: Developers, Git repository users
- **Pros**: Smaller installation, easy updates, excellent tooling
- **Cons**: Requires uv installation
- **Installation**: See [Installing uv](#installing-uv) below
### Linux
**uv (Package Manager)**
- **Only supported option** (no portable package available for Linux)
- **Best for**: All Linux users
- **Requires**: uv package manager
- **Backend**: vllm (default) or pt (PyTorch)
- **Installation**: See [Installing uv](#installing-uv) below
### macOS (Apple Silicon)
**uv with MLX Backend**
- **Only supported option** (no portable package available for macOS)
- **Best for**: All macOS Apple Silicon (M1/M2/M3/M4) users
- **Requires**: uv package manager
- **Backend**: mlx (native Apple Silicon acceleration)
- **Dedicated scripts**: `start_gradio_ui_macos.sh`, `start_api_server_macos.sh`
- **Installation**: See [Installing uv](#installing-uv) below
Note: Intel Macs can use the standard `start_gradio_ui.sh` with the PyTorch (pt) backend, but Apple Silicon Macs should use the macOS-specific scripts for optimal performance.
## Automatic Detection
### Windows (bat scripts)
The `.bat` startup scripts detect the environment in this order:
1. **First**: Check for `python_embeded\python.exe`
- If found: Use embedded Python directly
- If not found: Continue to step 2
2. **Second**: Check for `uv` command
- If found: Use uv
- If not found: Prompt to install uv
**Example output:**
```
[Environment] Using embedded Python...
```
or
```
[Environment] Embedded Python not found, checking for uv...
[Environment] Using uv package manager...
```
### Linux/macOS (sh scripts)
The `.sh` startup scripts detect the environment in this order:
1. **First**: Check for `uv` in PATH
- Also checks `~/.local/bin/uv` and `~/.cargo/bin/uv`
- If found: Use uv
- If not found: Prompt to install uv
2. **If not found**: Offer automatic installation
- Calls `install_uv.sh --silent` to install uv
- Updates PATH and continues
**Example output (Linux):**
```
[Environment] Using uv package manager...
```
**Example output (macOS):**
```
============================================
ACE-Step 1.5 - macOS Apple Silicon (MLX)
============================================
[Environment] Using uv package manager...
```
## Installing uv
### All Platforms
**Automatic**: When you run a startup script and uv is not found, you will be prompted:
```
uv package manager not found!
Install uv now? (Y/N):
```
Type `Y` and press Enter. The script will automatically install uv using the appropriate method for your platform.
### Windows Methods
**Method 1: PowerShell (Recommended)**
```powershell
irm https://astral.sh/uv/install.ps1 | iex
```
**Method 2: winget (Windows 10 1809+, Windows 11)**
```batch
winget install --id=astral-sh.uv -e
```
**Method 3: Run the install script**
```batch
install_uv.bat
```
The `install_uv.bat` script tries PowerShell first, then falls back to winget if PowerShell fails.
### Linux Methods
**Method 1: curl installer (Recommended)**
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
**Method 2: Run the install script**
```bash
chmod +x install_uv.sh
./install_uv.sh
```
The `install_uv.sh` script uses `curl` or `wget` to download and run the official installer.
### macOS Methods
**Method 1: curl installer (Recommended)**
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
**Method 2: Homebrew**
```bash
brew install uv
```
**Method 3: Run the install script**
```bash
chmod +x install_uv.sh
./install_uv.sh
```
The `install_uv.sh` script works on both Linux and macOS, and will suggest `brew install curl` on macOS if neither `curl` nor `wget` is available.
## Installation Locations
### Windows
**PowerShell installation:**
```
%USERPROFILE%\.local\bin\uv.exe
Example: C:\Users\YourName\.local\bin\uv.exe
```
**winget installation:**
```
%LOCALAPPDATA%\Microsoft\WinGet\Links\uv.exe
Example: C:\Users\YourName\AppData\Local\Microsoft\WinGet\Links\uv.exe
```
### Linux
**Default installation (curl installer):**
```
~/.local/bin/uv
Example: /home/yourname/.local/bin/uv
```
**Alternative location (cargo):**
```
~/.cargo/bin/uv
Example: /home/yourname/.cargo/bin/uv
```
### macOS
**Default installation (curl installer):**
```
~/.local/bin/uv
Example: /Users/yourname/.local/bin/uv
```
**Alternative location (cargo):**
```
~/.cargo/bin/uv
Example: /Users/yourname/.cargo/bin/uv
```
**Homebrew installation:**
```
/opt/homebrew/bin/uv (Apple Silicon)
/usr/local/bin/uv (Intel)
```
## First Run
### Windows with python_embeded
```batch
REM Download and extract portable package from:
REM https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z
REM Run the startup script
start_gradio_ui.bat
REM Output:
REM [Environment] Using embedded Python...
REM Starting ACE-Step Gradio UI...
```
### Windows with uv
```batch
REM First time: uv will create a virtual environment and sync dependencies
start_gradio_ui.bat
REM Output:
REM [Environment] Using uv package manager...
REM [Setup] Virtual environment not found. Setting up environment...
REM Running: uv sync
```
### Linux with uv
```bash
# Make scripts executable (first time only)
chmod +x start_gradio_ui.sh install_uv.sh
# First time: uv will create a virtual environment and sync dependencies
./start_gradio_ui.sh
# Output:
# [Environment] Using uv package manager...
# [Setup] Virtual environment not found. Setting up environment...
# Running: uv sync
```
### macOS (Apple Silicon) with uv
```bash
# Make scripts executable (first time only)
chmod +x start_gradio_ui_macos.sh install_uv.sh
# Use the macOS-specific script for MLX backend
./start_gradio_ui_macos.sh
# Output:
# ============================================
# ACE-Step 1.5 - macOS Apple Silicon (MLX)
# ============================================
# [Environment] Using uv package manager...
# [Setup] Virtual environment not found. Setting up environment...
# Running: uv sync
```
Note: On macOS Apple Silicon, always use `start_gradio_ui_macos.sh` instead of `start_gradio_ui.sh` to enable the MLX backend for native acceleration.
## Troubleshooting
### "uv not found" after installation
**Windows**
Cause: PATH not refreshed after installation.
Solution 1: Restart your terminal (close and reopen Command Prompt or PowerShell).
Solution 2: Use the full path temporarily:
```batch
%USERPROFILE%\.local\bin\uv.exe run acestep
```
**Linux/macOS**
Cause: uv installed but not in PATH.
Solution 1: Restart your terminal or source your profile:
```bash
source ~/.bashrc # or ~/.zshrc on macOS
```
Solution 2: Add uv to your PATH manually:
```bash
# For ~/.local/bin installation
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
# For macOS with zsh (default shell)
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
```
Solution 3: Use the full path temporarily:
```bash
~/.local/bin/uv run acestep
```
### Permission issues (Linux/macOS)
**Symptom**: `Permission denied` when running scripts.
**Solution**:
```bash
chmod +x start_gradio_ui.sh
chmod +x start_gradio_ui_macos.sh
chmod +x install_uv.sh
```
**Symptom**: `Permission denied` during uv installation.
**Solution**: The curl installer installs to `~/.local/bin` which should not require root. If you see permission errors:
```bash
# Ensure the directory exists and is writable
mkdir -p ~/.local/bin
```
Do not use `sudo` with the uv installer.
### winget not available (Windows)
**Symptom**:
```
'winget' is not recognized as an internal or external command
```
**Solution**:
- Windows 11: Should be pre-installed. Try updating Windows.
- Windows 10: Install "App Installer" from the Microsoft Store.
- Alternative: Use the PowerShell installation method instead:
```powershell
irm https://astral.sh/uv/install.ps1 | iex
```
### Installation fails
**Common causes**:
- Network connection issues
- Firewall blocking downloads
- Antivirus software interference (Windows)
- Missing `curl` or `wget` (Linux/macOS)
**Solutions**:
1. Check your internet connection.
2. Temporarily disable firewall/antivirus (Windows).
3. Try an alternative installation method:
- **Windows**: Use PowerShell method if winget fails, or vice versa.
- **Linux**: Install `curl` first (`sudo apt install curl` on Ubuntu/Debian, `sudo yum install curl` on CentOS/RHEL).
- **macOS**: Use `brew install uv` as an alternative.
4. **Windows only**: Use the portable package instead: https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z
## Switching Environments (Windows Only)
Windows is the only platform with two environment options. Linux and macOS use uv exclusively.
### From python_embeded to uv
```batch
REM 1. Install uv
install_uv.bat
REM 2. Rename or delete python_embeded folder
rename python_embeded python_embeded_backup
REM 3. Run startup script (will use uv)
start_gradio_ui.bat
```
### From uv to python_embeded
```batch
REM 1. Download portable package
REM https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z
REM 2. Extract python_embeded folder to project root
REM 3. Run startup script (will use python_embeded)
start_gradio_ui.bat
```
## Environment Variables (.env)
ACE-Step can be configured using environment variables in a `.env` file.
### Setup
```bash
# Copy the example file
cp .env.example .env
# Edit .env with your preferred settings
```
### Available Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `ACESTEP_INIT_LLM` | auto | LLM initialization control |
| `ACESTEP_CONFIG_PATH` | acestep-v15-turbo | DiT model path |
| `ACESTEP_LM_MODEL_PATH` | acestep-5Hz-lm-1.7B | LM model path |
| `ACESTEP_DEVICE` | auto | Device: auto, cuda, cpu, xpu |
| `ACESTEP_LM_BACKEND` | vllm | LM backend: vllm, pt, mlx |
| `ACESTEP_DOWNLOAD_SOURCE` | auto | Download source |
| `ACESTEP_API_KEY` | (none) | API authentication key |
### ACESTEP_LM_BACKEND
Controls which backend is used for the Language Model.
| Value | Platform | Description |
|-------|----------|-------------|
| `vllm` | Linux (CUDA) | Default. Fastest backend for NVIDIA GPUs. |
| `pt` | All | PyTorch native backend. Works everywhere but slower. |
| `mlx` | macOS (Apple Silicon) | Native Apple Silicon acceleration via MLX. |
**Platform-specific recommendations:**
- **Windows**: Use `vllm` (default) with NVIDIA GPU, or `pt` as fallback.
- **Linux**: Use `vllm` (default) with NVIDIA GPU, or `pt` as fallback.
- **macOS Apple Silicon**: Use `mlx` for best performance. The `start_gradio_ui_macos.sh` script sets this automatically via `export ACESTEP_LM_BACKEND="mlx"`.
**Example .env for macOS Apple Silicon:**
```bash
ACESTEP_LM_BACKEND=mlx
ACESTEP_CONFIG_PATH=acestep-v15-turbo
ACESTEP_LM_MODEL_PATH=acestep-5Hz-lm-0.6B
```
### ACESTEP_INIT_LLM - LLM Initialization Control
Controls whether the Language Model (5Hz LM) is initialized at startup.
**Processing Flow:**
```
GPU Detection (full) --> ACESTEP_INIT_LLM Override --> Model Loading
```
- GPU optimizations (offload, quantization, batch limits) are **always applied**
- `ACESTEP_INIT_LLM` only overrides the "should we load LLM" decision
- Model validation shows warnings but does not block when forcing
| Value | Behavior |
|-------|----------|
| `auto` (or empty) | Use GPU auto-detection result (recommended) |
| `true` / `1` / `yes` | Force enable LLM after GPU detection (may cause OOM) |
| `false` / `0` / `no` | Force disable for pure DiT mode |
**Example configurations:**
```bash
# Auto mode (recommended) - let GPU detection decide
ACESTEP_INIT_LLM=auto
# Auto mode - leave empty (same as above)
ACESTEP_INIT_LLM=
# Force enable on low VRAM GPU (GPU optimizations still applied)
ACESTEP_INIT_LLM=true
ACESTEP_LM_MODEL_PATH=acestep-5Hz-lm-0.6B # Use smallest model
# Force disable LLM for faster generation
ACESTEP_INIT_LLM=false
```
### Features Affected by LLM
When LLM is disabled (`ACESTEP_INIT_LLM=false`), these features are unavailable:
| Feature | Description | Available without LLM |
|---------|-------------|----------------------|
| Thinking mode | LLM generates audio codes | No |
| CoT caption | LLM enhances captions | No (auto-disabled) |
| CoT language | LLM detects vocal language | No (auto-disabled) |
| Sample mode | Generate from description | No |
| Format mode | LLM-enhanced input | No |
| Basic generation | DiT-based synthesis | Yes |
| Cover/Repaint | Audio editing tasks | Yes |
Note: When using the API server, CoT features (`use_cot_caption`, `use_cot_language`) are automatically disabled when LLM is unavailable, allowing basic generation to proceed.
## Environment Comparison
| Feature | python_embeded (Windows) | uv (Windows) | uv (Linux) | uv (macOS) |
|---------|--------------------------|---------------|-------------|-------------|
| Setup Difficulty | Zero config | Need install | Need install | Need install |
| Startup Speed | Fast | Fast | Fast | Fast |
| Update Ease | Re-download | uv command | uv command | uv command |
| Environment Isolation | Complete | Virtual env | Virtual env | Virtual env |
| Development | Basic | Excellent | Excellent | Excellent |
| Beginner Friendly | Best | Good | Good | Good |
| GPU Backend | CUDA | CUDA | CUDA (vllm) | MLX (Apple Silicon) |
| Install Script | N/A | install_uv.bat | install_uv.sh | install_uv.sh |
| Launch Script | start_gradio_ui.bat | start_gradio_ui.bat | start_gradio_ui.sh | start_gradio_ui_macos.sh |
## Recommendations
### Windows
**Use python_embeded if:**
- First time using ACE-Step
- Want zero configuration
- Do not need frequent updates
- Prefer a self-contained package
**Use uv if:**
- Developer or experienced with Python
- Need to modify dependencies
- Using the Git repository
- Want smaller installation size
- Need frequent code updates
### Linux
**Use uv (only option):**
- Install uv via the curl installer or `install_uv.sh`
- Use `start_gradio_ui.sh` to launch
- NVIDIA GPU with CUDA is recommended for vllm backend
- CPU-only is possible with `ACESTEP_DEVICE=cpu` and `ACESTEP_LM_BACKEND=pt`
### macOS (Apple Silicon)
**Use uv with MLX backend (recommended):**
- Install uv via curl installer, Homebrew, or `install_uv.sh`
- Use `start_gradio_ui_macos.sh` to launch (sets MLX backend automatically)
- The 0.6B LM model (`acestep-5Hz-lm-0.6B`) is recommended for devices with limited unified memory
- Set `ACESTEP_LM_BACKEND=mlx` in `.env` if launching manually
- Intel Macs should use `start_gradio_ui.sh` with `ACESTEP_LM_BACKEND=pt` instead
================================================
FILE: .claude/skills/acestep-docs/guides/GPU_COMPATIBILITY.md
================================================
# GPU Compatibility Guide
ACE-Step 1.5 automatically adapts to your GPU's available VRAM, adjusting generation limits and LM model availability accordingly. The system detects GPU memory at startup and configures optimal settings.
## GPU Tier Configuration
| VRAM | Tier | LM Mode | Max Duration | Max Batch Size | LM Memory Allocation |
|------|------|---------|--------------|----------------|---------------------|
| ≤4GB | Tier 1 | Not available | 3 min | 1 | - |
| 4-6GB | Tier 2 | Not available | 6 min | 1 | - |
| 6-8GB | Tier 3 | 0.6B (optional) | With LM: 4 min / Without: 6 min | With LM: 1 / Without: 2 | 3GB |
| 8-12GB | Tier 4 | 0.6B (optional) | With LM: 4 min / Without: 6 min | With LM: 2 / Without: 4 | 3GB |
| 12-16GB | Tier 5 | 0.6B / 1.7B | With LM: 4 min / Without: 6 min | With LM: 2 / Without: 4 | 0.6B: 3GB, 1.7B: 8GB |
| 16-24GB | Tier 6 | 0.6B / 1.7B / 4B | 8 min | With LM: 4 / Without: 8 | 0.6B: 3GB, 1.7B: 8GB, 4B: 12GB |
| ≥24GB | Unlimited | All models | 10 min | 8 | Unrestricted |
## Notes
- **Default settings** are automatically configured based on detected GPU memory
- **LM Mode** refers to the Language Model used for Chain-of-Thought generation and audio understanding
- **Flash Attention**, **CPU Offload**, **Compile**, and **Quantization** are enabled by default for optimal performance
- If you request a duration or batch size exceeding your GPU's limits, a warning will be displayed and values will be clamped
- **Constrained Decoding**: When LM is initialized, the LM's duration generation is also constrained to the GPU tier's maximum duration limit, preventing out-of-memory errors during CoT generation
- For GPUs with ≤6GB VRAM, LM initialization is disabled by default to preserve memory for the DiT model
- You can manually override settings via command-line arguments or the Gradio UI
## Overriding LLM Initialization
By default, LLM is auto-enabled/disabled based on GPU VRAM. You can override this behavior.
**Important:** GPU optimizations (offload, quantization, batch limits) are **always applied** regardless of override. `ACESTEP_INIT_LLM` only controls whether to attempt LLM loading.
### Processing Flow
```
GPU Detection (full) → ACESTEP_INIT_LLM Override → Model Loading
│ │ │
├─ offload settings ├─ auto: use GPU result ├─ Download model
├─ batch limits ├─ true: force enable ├─ Initialize LLM
├─ duration limits └─ false: force disable └─ (with GPU settings)
└─ recommended models
```
### Gradio UI
```bash
# Force enable LLM (may cause OOM on low VRAM)
uv run acestep --init_llm true
# Force disable LLM (pure DiT mode)
uv run acestep --init_llm false
```
Or in `start_gradio_ui.bat`:
```batch
set INIT_LLM=--init_llm true
```
### API Server
Using environment variable:
```bash
# Auto mode (recommended)
set ACESTEP_INIT_LLM=auto
uv run acestep-api
# Force enable LLM
set ACESTEP_INIT_LLM=true
uv run acestep-api
# Force disable LLM
set ACESTEP_INIT_LLM=false
uv run acestep-api
```
Or using command line:
```bash
uv run acestep-api --init-llm
```
Or in `start_api_server.bat`:
```batch
set ACESTEP_INIT_LLM=true
```
### When to Override
| Scenario | Setting | Notes |
|----------|---------|-------|
| Low VRAM but need thinking mode | `true` | May cause OOM, use with caution |
| Fast generation without CoT | `false` | Skips LLM, uses pure DiT |
| API server pure DiT mode | `false` | Faster responses, simpler setup |
| High VRAM but want minimal setup | `false` | No LLM model download needed |
### Features Affected by LLM
When LLM is disabled, these features are automatically disabled:
- **Thinking mode** (`thinking=true`)
- **CoT caption/language detection** (`use_cot_caption`, `use_cot_language`)
- **Sample mode** (generate from description)
- **Format mode** (LLM-enhanced input)
The API server will automatically fallback to pure DiT mode when these features are requested but LLM is unavailable.
> **Community Contributions Welcome**: The GPU tier configurations above are based on our testing across common hardware. If you find that your device's actual performance differs from these parameters (e.g., can handle longer durations or larger batch sizes), we welcome you to conduct more thorough testing and submit a PR to optimize these configurations in `acestep/gpu_config.py`. Your contributions help improve the experience for all users!
## Memory Optimization Tips
1. **Low VRAM (<8GB)**: Use DiT-only mode without LM initialization for maximum duration
2. **Medium VRAM (8-16GB)**: Use the 0.6B LM model for best balance of quality and memory
3. **High VRAM (>16GB)**: Enable larger LM models (1.7B/4B) for better audio understanding and generation quality
## Debug Mode: Simulating Different GPU Configurations
For testing and development, you can simulate different GPU memory sizes using the `MAX_CUDA_VRAM` environment variable:
```bash
# Simulate a 4GB GPU (Tier 1)
MAX_CUDA_VRAM=4 uv run acestep
# Simulate an 8GB GPU (Tier 4)
MAX_CUDA_VRAM=8 uv run acestep
# Simulate a 12GB GPU (Tier 5)
MAX_CUDA_VRAM=12 uv run acestep
# Simulate a 16GB GPU (Tier 6)
MAX_CUDA_VRAM=16 uv run acestep
```
This is useful for:
- Testing GPU tier configurations on high-end hardware
- Verifying that warnings and limits work correctly for each tier
- Developing and testing new GPU configuration parameters before submitting a PR
================================================
FILE: .claude/skills/acestep-docs/guides/GRADIO_GUIDE.md
================================================
# ACE-Step Gradio Demo User Guide
---
This guide provides comprehensive documentation for using the ACE-Step Gradio web interface for music generation, including all features and settings.
## Table of Contents
- [Getting Started](#getting-started)
- [Service Configuration](#service-configuration)
- [Generation Modes](#generation-modes)
- [Task Types](#task-types)
- [Input Parameters](#input-parameters)
- [Advanced Settings](#advanced-settings)
- [Results Section](#results-section)
- [LoRA Training](#lora-training)
- [Tips and Best Practices](#tips-and-best-practices)
---
## Getting Started
### Launching the Demo
```bash
# Basic launch
python app.py
# With pre-initialization
python app.py --config acestep-v15-turbo --init-llm
# With specific port
python app.py --port 7860
```
### Interface Overview
The Gradio interface consists of several main sections:
1. **Service Configuration** - Model loading and initialization
2. **Required Inputs** - Task type, audio uploads, and generation mode
3. **Music Caption & Lyrics** - Text inputs for generation
4. **Optional Parameters** - Metadata like BPM, key, duration
5. **Advanced Settings** - Fine-grained control over generation
6. **Results** - Generated audio playback and management
---
## Service Configuration
### Model Selection
| Setting | Description |
|---------|-------------|
| **Checkpoint File** | Select a trained model checkpoint (if available) |
| **Main Model Path** | Choose the DiT model configuration (e.g., `acestep-v15-turbo`, `acestep-v15-turbo-shift3`) |
| **Device** | Processing device: `auto` (recommended), `cuda`, or `cpu` |
### 5Hz LM Configuration
| Setting | Description |
|---------|-------------|
| **5Hz LM Model Path** | Select the language model (e.g., `acestep-5Hz-lm-0.6B`, `acestep-5Hz-lm-1.7B`) |
| **5Hz LM Backend** | `vllm` (faster, recommended) or `pt` (PyTorch, more compatible) |
| **Initialize 5Hz LM** | Check to load the LM during initialization (required for thinking mode) |
### Performance Options
| Setting | Description |
|---------|-------------|
| **Use Flash Attention** | Enable for faster inference (requires flash_attn package) |
| **Offload to CPU** | Offload models to CPU when idle to save GPU memory |
| **Offload DiT to CPU** | Specifically offload the DiT model to CPU |
### LoRA Adapter
| Setting | Description |
|---------|-------------|
| **LoRA Path** | Path to trained LoRA adapter directory |
| **Load LoRA** | Load the specified LoRA adapter |
| **Unload** | Remove the currently loaded LoRA |
| **Use LoRA** | Enable/disable the loaded LoRA for inference |
### Initialization
Click **Initialize Service** to load the models. The status box will show progress and confirmation.
---
## Generation Modes
### Simple Mode
Simple mode is designed for quick, natural language-based music generation.
**How to use:**
1. Select "Simple" in the Generation Mode radio button
2. Enter a natural language description in the "Song Description" field
3. Optionally check "Instrumental" if you don't want vocals
4. Optionally select a preferred vocal language
5. Click **Create Sample** to generate caption, lyrics, and metadata
6. Review the generated content in the expanded sections
7. Click **Generate Music** to create the audio
**Example descriptions:**
- "a soft Bengali love song for a quiet evening"
- "upbeat electronic dance music with heavy bass drops"
- "melancholic indie folk with acoustic guitar"
- "jazz trio playing in a smoky bar"
**Random Sample:** Click the 🎲 button to load a random example description.
### Custom Mode
Custom mode provides full control over all generation parameters.
**How to use:**
1. Select "Custom" in the Generation Mode radio button
2. Manually fill in the Caption and Lyrics fields
3. Set optional metadata (BPM, Key, Duration, etc.)
4. Optionally click **Format** to enhance your input using the LM
5. Configure advanced settings as needed
6. Click **Generate Music** to create the audio
---
## Task Types
### text2music (Default)
Generate music from text descriptions and/or lyrics.
**Use case:** Creating new music from scratch based on prompts.
**Required inputs:** Caption or Lyrics (at least one)
### cover
Transform existing audio while maintaining structure but changing style.
**Use case:** Creating cover versions in different styles.
**Required inputs:**
- Source Audio (upload in Audio Uploads section)
- Caption describing the target style
**Key parameter:** `Audio Cover Strength` (0.0-1.0)
- Higher values maintain more of the original structure
- Lower values allow more creative freedom
### repaint
Regenerate a specific time segment of audio.
**Use case:** Fixing or modifying specific sections of generated music.
**Required inputs:**
- Source Audio
- Repainting Start (seconds)
- Repainting End (seconds, -1 for end of file)
- Caption describing the desired content
### lego (Base Model Only)
Generate a specific instrument track in context of existing audio.
**Use case:** Adding instrument layers to backing tracks.
**Required inputs:**
- Source Audio
- Track Name (select from dropdown)
- Caption describing the track characteristics
**Available tracks:** vocals, backing_vocals, drums, bass, guitar, keyboard, percussion, strings, synth, fx, brass, woodwinds
### extract (Base Model Only)
Extract/isolate a specific instrument track from mixed audio.
**Use case:** Stem separation, isolating instruments.
**Required inputs:**
- Source Audio
- Track Name to extract
### complete (Base Model Only)
Complete partial tracks with specified instruments.
**Use case:** Auto-arranging incomplete compositions.
**Required inputs:**
- Source Audio
- Track Names (multiple selection)
- Caption describing the desired style
---
## Input Parameters
### Required Inputs
#### Task Type
Select the generation task from the dropdown. The instruction field updates automatically based on the selected task.
#### Audio Uploads
| Field | Description |
|-------|-------------|
| **Reference Audio** | Optional audio for style reference |
| **Source Audio** | Required for cover, repaint, lego, extract, complete tasks |
| **Convert to Codes** | Extract 5Hz semantic codes from source audio |
#### LM Codes Hints
Pre-computed audio semantic codes can be pasted here to guide generation. Use the **Transcribe** button to analyze codes and extract metadata.
### Music Caption
The text description of the desired music. Be specific about:
- Genre and style
- Instruments
- Mood and atmosphere
- Tempo feel (if not specifying BPM)
**Example:** "upbeat pop rock with electric guitars, driving drums, and catchy synth hooks"
Click 🎲 to load a random example caption.
### Lyrics
Enter lyrics with structure tags:
```
[Verse 1]
Walking down the street today
Thinking of the words you used to say
[Chorus]
I'm moving on, I'm staying strong
This is where I belong
[Verse 2]
...
```
**Instrumental checkbox:** Check this to generate instrumental music regardless of lyrics content.
**Vocal Language:** Select the language for vocals. Use "unknown" for auto-detection or instrumental tracks.
**Format button:** Click to enhance caption and lyrics using the 5Hz LM.
### Optional Parameters
| Parameter | Default | Description |
|-----------|---------|-------------|
| **BPM** | Auto | Tempo in beats per minute (30-300) |
| **Key Scale** | Auto | Musical key (e.g., "C Major", "Am", "F# minor") |
| **Time Signature** | Auto | Time signature: 2 (2/4), 3 (3/4), 4 (4/4), 6 (6/8) |
| **Audio Duration** | Auto/-1 | Target length in seconds (10-600). -1 for automatic |
| **Batch Size** | 2 | Number of audio variations to generate (1-8) |
---
## Advanced Settings
### DiT Parameters
| Parameter | Default | Description |
|-----------|---------|-------------|
| **Inference Steps** | 8 | Denoising steps. Turbo: 1-20, Base: 1-200 |
| **Guidance Scale** | 7.0 | CFG strength (base model only). Higher = follows prompt more |
| **Seed** | -1 | Random seed. Use comma-separated values for batches |
| **Random Seed** | ✓ | When checked, generates random seeds |
| **Audio Format** | mp3 | Output format: mp3, flac |
| **Shift** | 3.0 | Timestep shift factor (1.0-5.0). Recommended 3.0 for turbo |
| **Inference Method** | ode | ode (Euler, faster) or sde (stochastic) |
| **Custom Timesteps** | - | Override timesteps (e.g., "0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0") |
### Base Model Only Parameters
| Parameter | Default | Description |
|-----------|---------|-------------|
| **Use ADG** | ✗ | Enable Adaptive Dual Guidance for better quality |
| **CFG Interval Start** | 0.0 | When to start applying CFG (0.0-1.0) |
| **CFG Interval End** | 1.0 | When to stop applying CFG (0.0-1.0) |
### LM Parameters
| Parameter | Default | Description |
|-----------|---------|-------------|
| **LM Temperature** | 0.85 | Sampling temperature (0.0-2.0). Higher = more creative |
| **LM CFG Scale** | 2.0 | LM guidance strength (1.0-3.0) |
| **LM Top-K** | 0 | Top-K sampling. 0 disables |
| **LM Top-P** | 0.9 | Nucleus sampling (0.0-1.0) |
| **LM Negative Prompt** | "NO USER INPUT" | Negative prompt for CFG |
### CoT (Chain-of-Thought) Options
| Option | Default | Description |
|--------|---------|-------------|
| **CoT Metas** | ✓ | Generate metadata via LM reasoning |
| **CoT Language** | ✓ | Detect vocal language via LM |
| **Constrained Decoding Debug** | ✗ | Enable debug logging |
### Generation Options
| Option | Default | Description |
|--------|---------|-------------|
| **LM Codes Strength** | 1.0 | How strongly LM codes influence generation (0.0-1.0) |
| **Auto Score** | ✗ | Automatically calculate quality scores |
| **Auto LRC** | ✗ | Automatically generate lyrics timestamps |
| **LM Batch Chunk Size** | 8 | Max items per LM batch (GPU memory) |
### Main Generation Controls
| Control | Description |
|---------|-------------|
| **Think** | Enable 5Hz LM for code generation and metadata |
| **ParallelThinking** | Enable parallel LM batch processing |
| **CaptionRewrite** | Let LM enhance the input caption |
| **AutoGen** | Automatically start next batch after completion |
---
## Results Section
### Generated Audio
Up to 8 audio samples are displayed based on batch size. Each sample includes:
- **Audio Player** - Play, pause, and download the generated audio
- **Send To Src** - Send this audio to the Source Audio input for further processing
- **Save** - Save audio and metadata to a JSON file
- **Score** - Calculate perplexity-based quality score
- **LRC** - Generate lyrics timestamps (LRC format)
### Details Accordion
Click "Score & LRC & LM Codes" to expand and view:
- **LM Codes** - The 5Hz semantic codes for this sample
- **Quality Score** - Perplexity-based quality metric
- **Lyrics Timestamps** - LRC format timing data
### Batch Navigation
| Control | Description |
|---------|-------------|
| **◀ Previous** | View the previous batch |
| **Batch Indicator** | Shows current batch position (e.g., "Batch 1 / 3") |
| **Next Batch Status** | Shows background generation progress |
| **Next ▶** | View the next batch (triggers generation if AutoGen is on) |
### Restore Parameters
Click **Apply These Settings to UI** to restore all generation parameters from the current batch back to the input fields. Useful for iterating on a good result.
### Batch Results
The "Batch Results & Generation Details" accordion contains:
- **All Generated Files** - Download all files from all batches
- **Generation Details** - Detailed information about the generation process
---
## LoRA Training
The LoRA Training tab provides tools for creating custom LoRA adapters.
### Dataset Builder Tab
#### Step 1: Load or Scan
**Option A: Load Existing Dataset**
1. Enter the path to a previously saved dataset JSON
2. Click **Load**
**Option B: Scan New Directory**
1. Enter the path to your audio folder
2. Click **Scan** to find audio files (wav, mp3, flac, ogg, opus)
#### Step 2: Configure Dataset
| Setting | Description |
|---------|-------------|
| **Dataset Name** | Name for your dataset |
| **All Instrumental** | Check if all tracks have no vocals |
| **Custom Activation Tag** | Unique tag to activate this LoRA's style |
| **Tag Position** | Where to place the tag: Prepend, Append, or Replace caption |
#### Step 3: Auto-Label
Click **Auto-Label All** to generate metadata for all audio files:
- Caption (music description)
- BPM
- Key
- Time Signature
**Skip Metas** option will skip LLM labeling and use N/A values.
#### Step 4: Preview & Edit
Use the slider to select samples and manually edit:
- Caption
- Lyrics
- BPM, Key, Time Signature
- Language
- Instrumental flag
Click **Save Changes** to update the sample.
#### Step 5: Save Dataset
Enter a save path and click **Save Dataset** to export as JSON.
#### Step 6: Preprocess
Convert the dataset to pre-computed tensors for fast training:
1. Optionally load an existing dataset JSON
2. Set the tensor output directory
3. Click **Preprocess**
This encodes audio to VAE latents, text to embeddings, and runs the condition encoder.
### Train LoRA Tab
#### Dataset Selection
Enter the path to preprocessed tensors directory and click **Load Dataset**.
#### LoRA Settings
| Setting | Default | Description |
|---------|---------|-------------|
| **LoRA Rank (r)** | 64 | Capacity of LoRA. Higher = more capacity, more memory |
| **LoRA Alpha** | 128 | Scaling factor (typically 2x rank) |
| **LoRA Dropout** | 0.1 | Dropout rate for regularization |
#### Training Parameters
| Setting | Default | Description |
|---------|---------|-------------|
| **Learning Rate** | 1e-4 | Optimization learning rate |
| **Max Epochs** | 500 | Maximum training epochs |
| **Batch Size** | 1 | Training batch size |
| **Gradient Accumulation** | 1 | Effective batch = batch_size × accumulation |
| **Save Every N Epochs** | 200 | Checkpoint save frequency |
| **Shift** | 3.0 | Timestep shift for turbo model |
| **Seed** | 42 | Random seed for reproducibility |
#### Training Controls
- **Start Training** - Begin the training process
- **Stop Training** - Interrupt training
- **Training Progress** - Shows current epoch and loss
- **Training Log** - Detailed training output
- **Training Loss Plot** - Visual loss curve
#### Export LoRA
After training, export the final adapter:
1. Enter the export path
2. Click **Export LoRA**
---
## Tips and Best Practices
### For Best Quality
1. **Use thinking mode** - Keep "Think" checkbox enabled for LM-enhanced generation
2. **Be specific in captions** - Include genre, instruments, mood, and style details
3. **Let LM detect metadata** - Leave BPM/Key/Duration empty for auto-detection
4. **Use batch generation** - Generate 2-4 variations and pick the best
### For Faster Generation
1. **Use turbo model** - Select `acestep-v15-turbo` or `acestep-v15-turbo-shift3`
2. **Keep inference steps at 8** - Default is optimal for turbo
3. **Reduce batch size** - Lower batch size if you need quick results
4. **Disable AutoGen** - Manual control over batch generation
### For Consistent Results
1. **Set a specific seed** - Uncheck "Random Seed" and enter a seed value
2. **Save good results** - Use "Save" to export parameters for reproduction
3. **Use "Apply These Settings"** - Restore parameters from a good batch
### For Long-form Music
1. **Set explicit duration** - Specify duration in seconds
2. **Use repaint task** - Fix problematic sections after initial generation
3. **Chain generations** - Use "Send To Src" to build upon previous results
### For Style Consistency
1. **Train a LoRA** - Create a custom adapter for your style
2. **Use reference audio** - Upload style reference in Audio Uploads
3. **Use consistent captions** - Maintain similar descriptive language
### Troubleshooting
**No audio generated:**
- Check that the model is initialized (green status message)
- Ensure 5Hz LM is initialized if using thinking mode
- Check the status output for error messages
**Poor quality results:**
- Increase inference steps (for base model)
- Adjust guidance scale
- Try different seeds
- Make caption more specific
**Out of memory:**
- Reduce batch size
- Enable CPU offloading
- Reduce LM batch chunk size
**LM not working:**
- Ensure "Initialize 5Hz LM" was checked during initialization
- Check that a valid LM model path is selected
- Verify vllm or PyTorch backend is available
---
## Keyboard Shortcuts
The Gradio interface supports standard web shortcuts:
- **Tab** - Move between input fields
- **Enter** - Submit text inputs
- **Space** - Toggle checkboxes
---
## Language Support
The interface supports multiple UI languages:
- **English** (en)
- **Chinese** (zh)
- **Japanese** (ja)
Select your preferred language in the Service Configuration section.
---
For more information, see:
- Main README: [`../../README.md`](../../README.md)
- REST API Documentation: [`API.md`](API.md)
- Python Inference API: [`INFERENCE.md`](INFERENCE.md)
================================================
FILE: .claude/skills/acestep-docs/guides/INFERENCE.md
================================================
# ACE-Step Inference API Documentation
---
This document provides comprehensive documentation for the ACE-Step inference API, including parameter specifications for all supported task types.
## Table of Contents
- [Quick Start](#quick-start)
- [API Overview](#api-overview)
- [GenerationParams P
gitextract_6lqx4nhl/
├── .claude/
│ └── skills/
│ ├── acestep/
│ │ ├── SKILL.md
│ │ ├── api-reference.md
│ │ └── scripts/
│ │ ├── acestep.sh
│ │ └── config.example.json
│ ├── acestep-docs/
│ │ ├── SKILL.md
│ │ ├── api/
│ │ │ ├── API.md
│ │ │ └── Openrouter_API.md
│ │ ├── getting-started/
│ │ │ ├── ABOUT.md
│ │ │ ├── README.md
│ │ │ └── Tutorial.md
│ │ └── guides/
│ │ ├── ENVIRONMENT_SETUP.md
│ │ ├── GPU_COMPATIBILITY.md
│ │ ├── GRADIO_GUIDE.md
│ │ ├── INFERENCE.md
│ │ ├── SCRIPT_CONFIGURATION.md
│ │ └── UPDATE_AND_BACKUP.md
│ ├── acestep-lyrics-transcription/
│ │ ├── SKILL.md
│ │ └── scripts/
│ │ ├── acestep-lyrics-transcription.sh
│ │ └── config.example.json
│ ├── acestep-simplemv/
│ │ ├── SKILL.md
│ │ └── scripts/
│ │ ├── package.json
│ │ ├── remotion.config.ts
│ │ ├── render-mv.sh
│ │ ├── render.mjs
│ │ ├── render.sh
│ │ ├── src/
│ │ │ ├── AudioVisualization.tsx
│ │ │ ├── Root.tsx
│ │ │ ├── index.ts
│ │ │ ├── parseLrc.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── acestep-songwriting/
│ │ └── SKILL.md
│ └── acestep-thumbnail/
│ ├── SKILL.md
│ └── scripts/
│ ├── acestep-thumbnail.sh
│ └── config.example.json
├── .dockerignore
├── .editorconfig
├── .githooks/
│ └── pre-push
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── codeql-config.yml
│ ├── copilot-instructions.md
│ └── workflows/
│ ├── close-inactive-issues.yml
│ ├── codeql.yml
│ └── docs.yml
├── .gitignore
├── AGENTS.md
├── CONTRIBUTING.md
├── Dockerfile.jetson
├── LICENSE
├── README-XPU.md
├── README.md
├── SECURITY.md
├── acestep/
│ ├── __init__.py
│ ├── acestep_v15_pipeline.py
│ ├── api/
│ │ ├── __init__.py
│ │ ├── http/
│ │ │ ├── __init__.py
│ │ │ ├── audio_route.py
│ │ │ ├── audio_route_http_test.py
│ │ │ ├── audio_route_test.py
│ │ │ ├── auth.py
│ │ │ ├── auth_test.py
│ │ │ ├── lora_routes.py
│ │ │ ├── lora_routes_http_test.py
│ │ │ ├── lora_routes_test.py
│ │ │ ├── model_init_service.py
│ │ │ ├── model_init_service_test.py
│ │ │ ├── model_service_routes.py
│ │ │ ├── model_service_routes_http_test.py
│ │ │ ├── model_service_routes_test.py
│ │ │ ├── query_result_route.py
│ │ │ ├── query_result_route_http_test.py
│ │ │ ├── query_result_route_test.py
│ │ │ ├── query_result_service.py
│ │ │ ├── reinitialize_route.py
│ │ │ ├── reinitialize_route_http_test.py
│ │ │ ├── reinitialize_route_test.py
│ │ │ ├── release_task_audio_paths.py
│ │ │ ├── release_task_audio_paths_test.py
│ │ │ ├── release_task_models.py
│ │ │ ├── release_task_models_test.py
│ │ │ ├── release_task_param_parser.py
│ │ │ ├── release_task_param_parser_test.py
│ │ │ ├── release_task_request_builder.py
│ │ │ ├── release_task_request_builder_test.py
│ │ │ ├── release_task_request_parser.py
│ │ │ ├── release_task_request_parser_test.py
│ │ │ ├── release_task_route.py
│ │ │ ├── release_task_route_http_test.py
│ │ │ ├── sample_format_routes.py
│ │ │ ├── sample_format_routes_http_test.py
│ │ │ └── sample_format_routes_test.py
│ │ ├── job_analysis_runtime.py
│ │ ├── job_analysis_runtime_test.py
│ │ ├── job_blocking_generation.py
│ │ ├── job_blocking_generation_test.py
│ │ ├── job_execution_runtime.py
│ │ ├── job_execution_runtime_test.py
│ │ ├── job_generation_runtime.py
│ │ ├── job_generation_runtime_test.py
│ │ ├── job_generation_setup.py
│ │ ├── job_generation_setup_test.py
│ │ ├── job_llm_preparation.py
│ │ ├── job_llm_preparation_test.py
│ │ ├── job_model_selection.py
│ │ ├── job_model_selection_test.py
│ │ ├── job_result_payload.py
│ │ ├── job_result_payload_test.py
│ │ ├── job_runtime_state.py
│ │ ├── job_runtime_state_test.py
│ │ ├── jobs/
│ │ │ ├── __init__.py
│ │ │ ├── local_cache_updates.py
│ │ │ ├── local_cache_updates_test.py
│ │ │ ├── models.py
│ │ │ ├── store.py
│ │ │ ├── store_test.py
│ │ │ ├── test_fakes.py
│ │ │ ├── worker_loops.py
│ │ │ └── worker_loops_test.py
│ │ ├── lifespan_runtime.py
│ │ ├── lifespan_runtime_test.py
│ │ ├── llm_generation_inputs.py
│ │ ├── llm_readiness.py
│ │ ├── log_capture.py
│ │ ├── log_capture_test.py
│ │ ├── model_download.py
│ │ ├── model_download_test.py
│ │ ├── route_setup.py
│ │ ├── route_setup_test.py
│ │ ├── runtime_helpers.py
│ │ ├── runtime_helpers_test.py
│ │ ├── server_cli.py
│ │ ├── server_cli_test.py
│ │ ├── server_utils.py
│ │ ├── server_utils_test.py
│ │ ├── startup_llm_init.py
│ │ ├── startup_llm_init_test.py
│ │ ├── startup_model_init.py
│ │ ├── startup_model_init_test.py
│ │ ├── train_api_dataset_auto_label_async_route.py
│ │ ├── train_api_dataset_auto_label_routes.py
│ │ ├── train_api_dataset_auto_label_routes_http_test.py
│ │ ├── train_api_dataset_auto_label_status_route.py
│ │ ├── train_api_dataset_auto_label_sync_route.py
│ │ ├── train_api_dataset_models.py
│ │ ├── train_api_dataset_models_test.py
│ │ ├── train_api_dataset_preprocess_routes.py
│ │ ├── train_api_dataset_preprocess_routes_http_test.py
│ │ ├── train_api_dataset_sample_routes.py
│ │ ├── train_api_dataset_sample_routes_http_test.py
│ │ ├── train_api_dataset_scan_load_routes.py
│ │ ├── train_api_dataset_scan_load_routes_http_test.py
│ │ ├── train_api_dataset_service.py
│ │ ├── train_api_dataset_service_http_test.py
│ │ ├── train_api_dataset_status_routes.py
│ │ ├── train_api_dataset_status_routes_http_test.py
│ │ ├── train_api_lokr_start_route.py
│ │ ├── train_api_lora_start_route.py
│ │ ├── train_api_models.py
│ │ ├── train_api_runtime.py
│ │ ├── train_api_service.py
│ │ ├── train_api_service_http_test.py
│ │ ├── worker_runtime.py
│ │ └── worker_runtime_test.py
│ ├── api_server.py
│ ├── audio_utils.py
│ ├── audio_utils_test.py
│ ├── audio_utils_uuid_test.py
│ ├── cli_args.py
│ ├── cli_args_test.py
│ ├── constants.py
│ ├── constrained_logits_processor.py
│ ├── core/
│ │ ├── __init__.py
│ │ ├── audio/
│ │ │ └── __init__.py
│ │ ├── generation/
│ │ │ ├── __init__.py
│ │ │ └── handler/
│ │ │ ├── __init__.py
│ │ │ ├── audio_codes.py
│ │ │ ├── batch_prep.py
│ │ │ ├── conditioning_batch.py
│ │ │ ├── conditioning_batch_test.py
│ │ │ ├── conditioning_embed.py
│ │ │ ├── conditioning_embed_test.py
│ │ │ ├── conditioning_masks.py
│ │ │ ├── conditioning_masks_test.py
│ │ │ ├── conditioning_target.py
│ │ │ ├── conditioning_text.py
│ │ │ ├── cover_noise_strength_forwarding_test.py
│ │ │ ├── diffusion.py
│ │ │ ├── diffusion_test.py
│ │ │ ├── generate_music.py
│ │ │ ├── generate_music_decode.py
│ │ │ ├── generate_music_decode_test.py
│ │ │ ├── generate_music_execute.py
│ │ │ ├── generate_music_execute_test.py
│ │ │ ├── generate_music_payload.py
│ │ │ ├── generate_music_payload_test.py
│ │ │ ├── generate_music_request.py
│ │ │ ├── generate_music_request_test.py
│ │ │ ├── generate_music_test.py
│ │ │ ├── init_service.py
│ │ │ ├── init_service_catalog.py
│ │ │ ├── init_service_downloads.py
│ │ │ ├── init_service_loader.py
│ │ │ ├── init_service_loader_components.py
│ │ │ ├── init_service_memory_basic.py
│ │ │ ├── init_service_memory_transfer.py
│ │ │ ├── init_service_offload_context.py
│ │ │ ├── init_service_orchestrator.py
│ │ │ ├── init_service_setup.py
│ │ │ ├── init_service_test.py
│ │ │ ├── io_audio.py
│ │ │ ├── io_audio_test.py
│ │ │ ├── lora/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── adapter_discovery.py
│ │ │ │ ├── controls.py
│ │ │ │ ├── controls_test.py
│ │ │ │ ├── lifecycle.py
│ │ │ │ ├── lifecycle_test.py
│ │ │ │ ├── registry_builder.py
│ │ │ │ ├── registry_state.py
│ │ │ │ └── scale_apply.py
│ │ │ ├── lora_integration_test.py
│ │ │ ├── lora_manager.py
│ │ │ ├── lyric_alignment_common.py
│ │ │ ├── lyric_alignment_test.py
│ │ │ ├── lyric_score.py
│ │ │ ├── lyric_timestamp.py
│ │ │ ├── memory_utils.py
│ │ │ ├── metadata_utils.py
│ │ │ ├── mlx_dit_init.py
│ │ │ ├── mlx_dit_init_test.py
│ │ │ ├── mlx_vae_decode_native.py
│ │ │ ├── mlx_vae_encode_native.py
│ │ │ ├── mlx_vae_init.py
│ │ │ ├── mlx_vae_init_test.py
│ │ │ ├── mlx_vae_native_test.py
│ │ │ ├── padding_utils.py
│ │ │ ├── progress.py
│ │ │ ├── progress_project_root_test.py
│ │ │ ├── prompt_utils.py
│ │ │ ├── reference_audio_validation_test.py
│ │ │ ├── repaint_step_injection.py
│ │ │ ├── repaint_step_injection_test.py
│ │ │ ├── repaint_waveform_splice.py
│ │ │ ├── repaint_waveform_splice_test.py
│ │ │ ├── resolve_repaint_config_test.py
│ │ │ ├── service_generate.py
│ │ │ ├── service_generate_execute.py
│ │ │ ├── service_generate_execute_test.py
│ │ │ ├── service_generate_outputs.py
│ │ │ ├── service_generate_request.py
│ │ │ ├── service_generate_request_test.py
│ │ │ ├── service_generate_test.py
│ │ │ ├── task_utils.py
│ │ │ ├── task_utils_test.py
│ │ │ ├── training_preset.py
│ │ │ ├── training_preset_test.py
│ │ │ ├── vae_decode.py
│ │ │ ├── vae_decode_chunks.py
│ │ │ ├── vae_decode_chunks_test.py
│ │ │ ├── vae_decode_mixin_test.py
│ │ │ ├── vae_decode_test_helpers.py
│ │ │ ├── vae_encode.py
│ │ │ ├── vae_encode_chunks.py
│ │ │ └── vae_encode_test.py
│ │ ├── llm/
│ │ │ └── __init__.py
│ │ ├── lora/
│ │ │ ├── __init__.py
│ │ │ ├── introspection.py
│ │ │ ├── registry.py
│ │ │ ├── scaling.py
│ │ │ ├── service.py
│ │ │ └── service_test.py
│ │ ├── scoring/
│ │ │ ├── __init__.py
│ │ │ ├── _dtw.py
│ │ │ ├── dit_alignment.py
│ │ │ ├── dit_score.py
│ │ │ ├── lm_score.py
│ │ │ └── scoring_test.py
│ │ └── system/
│ │ └── __init__.py
│ ├── dataset/
│ │ ├── __init__.py
│ │ ├── builder/
│ │ │ └── __init__.py
│ │ └── runtime/
│ │ └── __init__.py
│ ├── dataset_handler.py
│ ├── debug_utils.py
│ ├── genres_vocab.txt
│ ├── gpu_config.py
│ ├── gpu_config_effective_free_vram_test.py
│ ├── handler.py
│ ├── inference.py
│ ├── launcher_compat.py
│ ├── launcher_compat_test.py
│ ├── launcher_legacy_torch_fix_test.py
│ ├── llm_backend_compat.py
│ ├── llm_backend_compat_test.py
│ ├── llm_inference.py
│ ├── llm_inference_cache_cleanup_test.py
│ ├── llm_inference_cfg_fixes_test.py
│ ├── llm_inference_dist_cleanup_test.py
│ ├── llm_inference_enforce_eager_test.py
│ ├── local_cache.py
│ ├── local_cache_thread_safety_test.py
│ ├── model_downloader.py
│ ├── model_downloader_test.py
│ ├── models/
│ │ ├── __init__.py
│ │ ├── base/
│ │ │ ├── __init__.py
│ │ │ ├── apg_guidance.py
│ │ │ ├── configuration_acestep_v15.py
│ │ │ └── modeling_acestep_v15_base.py
│ │ ├── mlx/
│ │ │ ├── __init__.py
│ │ │ ├── dit_convert.py
│ │ │ ├── dit_generate.py
│ │ │ ├── dit_model.py
│ │ │ ├── vae_convert.py
│ │ │ └── vae_model.py
│ │ ├── sft/
│ │ │ ├── __init__.py
│ │ │ ├── apg_guidance.py
│ │ │ ├── configuration_acestep_v15.py
│ │ │ └── modeling_acestep_v15_base.py
│ │ └── turbo/
│ │ ├── __init__.py
│ │ ├── configuration_acestep_v15.py
│ │ └── modeling_acestep_v15_turbo.py
│ ├── null_duration_fixes_test.py
│ ├── openrouter_adapter.py
│ ├── openrouter_models.py
│ ├── text2music_src_audio_test.py
│ ├── third_parts/
│ │ └── nano-vllm/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── bench.py
│ │ ├── example.py
│ │ ├── nanovllm/
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── distributed.py
│ │ │ ├── engine/
│ │ │ │ ├── block_manager.py
│ │ │ │ ├── llm_engine.py
│ │ │ │ ├── model_runner.py
│ │ │ │ ├── scheduler.py
│ │ │ │ └── sequence.py
│ │ │ ├── layers/
│ │ │ │ ├── activation.py
│ │ │ │ ├── attention.py
│ │ │ │ ├── embed_head.py
│ │ │ │ ├── layernorm.py
│ │ │ │ ├── linear.py
│ │ │ │ ├── rotary_embedding.py
│ │ │ │ └── sampler.py
│ │ │ ├── llm.py
│ │ │ ├── models/
│ │ │ │ └── qwen3.py
│ │ │ ├── sampling_params.py
│ │ │ └── utils/
│ │ │ ├── compat.py
│ │ │ ├── compat_test.py
│ │ │ ├── context.py
│ │ │ └── loader.py
│ │ └── pyproject.toml
│ ├── training/
│ │ ├── __init__.py
│ │ ├── configs.py
│ │ ├── data_module.py
│ │ ├── data_module_test.py
│ │ ├── dataset_builder.py
│ │ ├── dataset_builder_modules/
│ │ │ ├── __init__.py
│ │ │ ├── audio_io.py
│ │ │ ├── builder.py
│ │ │ ├── core.py
│ │ │ ├── csv_metadata.py
│ │ │ ├── dataframe.py
│ │ │ ├── label_all.py
│ │ │ ├── label_single.py
│ │ │ ├── label_utils.py
│ │ │ ├── metadata.py
│ │ │ ├── models.py
│ │ │ ├── preprocess.py
│ │ │ ├── preprocess_audio.py
│ │ │ ├── preprocess_context.py
│ │ │ ├── preprocess_encoder.py
│ │ │ ├── preprocess_lyrics.py
│ │ │ ├── preprocess_manifest.py
│ │ │ ├── preprocess_text.py
│ │ │ ├── preprocess_utils.py
│ │ │ ├── preprocess_vae.py
│ │ │ ├── scan.py
│ │ │ ├── serialization.py
│ │ │ └── update_sample.py
│ │ ├── lokr_utils.py
│ │ ├── lora_checkpoint.py
│ │ ├── lora_injection.py
│ │ ├── lora_utils.py
│ │ ├── path_safety.py
│ │ ├── test_lora_utils.py
│ │ └── trainer.py
│ ├── training_v2/
│ │ ├── __init__.py
│ │ ├── cli/
│ │ │ ├── __init__.py
│ │ │ ├── args.py
│ │ │ ├── common.py
│ │ │ ├── config_builder.py
│ │ │ ├── train_fixed.py
│ │ │ ├── train_vanilla.py
│ │ │ └── validation.py
│ │ ├── configs.py
│ │ ├── estimate.py
│ │ ├── fixed_lora_module.py
│ │ ├── gpu_utils.py
│ │ ├── make_test_fixtures.py
│ │ ├── model_discovery.py
│ │ ├── model_loader.py
│ │ ├── optim.py
│ │ ├── preprocess.py
│ │ ├── preprocess_discovery.py
│ │ ├── preprocess_prompt.py
│ │ ├── preprocess_vae.py
│ │ ├── presets/
│ │ │ ├── high_quality.json
│ │ │ ├── quick_test.json
│ │ │ ├── recommended.json
│ │ │ ├── vram_12gb.json
│ │ │ ├── vram_16gb.json
│ │ │ ├── vram_24gb_plus.json
│ │ │ └── vram_8gb.json
│ │ ├── settings.py
│ │ ├── tensorboard_utils.py
│ │ ├── timestep_sampling.py
│ │ ├── trainer_basic_loop.py
│ │ ├── trainer_fixed.py
│ │ ├── trainer_helpers.py
│ │ ├── trainer_helpers_test.py
│ │ ├── trainer_vanilla.py
│ │ └── ui/
│ │ ├── __init__.py
│ │ ├── banner.py
│ │ ├── config_panel.py
│ │ ├── errors.py
│ │ ├── flows.py
│ │ ├── flows_common.py
│ │ ├── flows_estimate.py
│ │ ├── flows_preprocess.py
│ │ ├── flows_setup.py
│ │ ├── flows_train.py
│ │ ├── flows_train_steps.py
│ │ ├── gpu_monitor.py
│ │ ├── help_formatter.py
│ │ ├── presets.py
│ │ ├── progress.py
│ │ ├── prompt_helpers.py
│ │ ├── summary.py
│ │ ├── wizard.py
│ │ └── wizard_menus.py
│ └── ui/
│ ├── __init__.py
│ ├── gradio/
│ │ ├── __init__.py
│ │ ├── api/
│ │ │ ├── __init__.py
│ │ │ ├── api_routes.py
│ │ │ ├── api_routes_resource_test.py
│ │ │ └── api_routes_thread_safety_test.py
│ │ ├── events/
│ │ │ ├── __init__.py
│ │ │ ├── generation/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── llm_action_params.py
│ │ │ │ ├── llm_actions.py
│ │ │ │ ├── llm_analysis_actions.py
│ │ │ │ ├── llm_format_actions.py
│ │ │ │ ├── llm_sample_actions.py
│ │ │ │ ├── metadata_loading.py
│ │ │ │ ├── mode_ui.py
│ │ │ │ ├── mode_ui_helpers.py
│ │ │ │ ├── mode_ui_test.py
│ │ │ │ ├── model_config.py
│ │ │ │ ├── model_config_test.py
│ │ │ │ ├── service_init.py
│ │ │ │ ├── service_init_test.py
│ │ │ │ ├── ui_helpers.py
│ │ │ │ └── validation.py
│ │ │ ├── generation_handlers.py
│ │ │ ├── generation_handlers_test.py
│ │ │ ├── results/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _batch_management_test_support.py
│ │ │ │ ├── audio_playback_updates.py
│ │ │ │ ├── audio_playback_updates_test.py
│ │ │ │ ├── audio_transfer.py
│ │ │ │ ├── batch_management.py
│ │ │ │ ├── batch_management_background.py
│ │ │ │ ├── batch_management_background_test.py
│ │ │ │ ├── batch_management_helpers.py
│ │ │ │ ├── batch_management_helpers_test.py
│ │ │ │ ├── batch_management_test.py
│ │ │ │ ├── batch_management_wrapper.py
│ │ │ │ ├── batch_navigation.py
│ │ │ │ ├── batch_navigation_test.py
│ │ │ │ ├── batch_queue.py
│ │ │ │ ├── batch_queue_test.py
│ │ │ │ ├── generation_info.py
│ │ │ │ ├── generation_info_test.py
│ │ │ │ ├── generation_progress.py
│ │ │ │ ├── lrc_utils.py
│ │ │ │ ├── lrc_utils_test.py
│ │ │ │ └── scoring.py
│ │ │ ├── results_handlers.py
│ │ │ ├── results_handlers_facade_test.py
│ │ │ ├── training/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── dataset_ops.py
│ │ │ │ ├── dataset_ops_test.py
│ │ │ │ ├── lokr_training.py
│ │ │ │ ├── lora_training.py
│ │ │ │ ├── preprocess.py
│ │ │ │ ├── preprocess_test.py
│ │ │ │ ├── training_facade_test.py
│ │ │ │ ├── training_utils.py
│ │ │ │ └── training_utils_test.py
│ │ │ ├── training_handlers.py
│ │ │ └── wiring/
│ │ │ ├── __init__.py
│ │ │ ├── ast_test_utils.py
│ │ │ ├── context.py
│ │ │ ├── context_test.py
│ │ │ ├── decomposition_contract_generation_test.py
│ │ │ ├── decomposition_contract_helpers.py
│ │ │ ├── decomposition_contract_training_test.py
│ │ │ ├── docstring_coverage_test.py
│ │ │ ├── generation_batch_navigation_wiring.py
│ │ │ ├── generation_metadata_file_wiring.py
│ │ │ ├── generation_metadata_file_wiring_test.py
│ │ │ ├── generation_metadata_wiring.py
│ │ │ ├── generation_mode_wiring.py
│ │ │ ├── generation_run_wiring.py
│ │ │ ├── generation_service_wiring.py
│ │ │ ├── generation_service_wiring_test.py
│ │ │ ├── generation_text_format_wiring.py
│ │ │ ├── results_aux_wiring.py
│ │ │ ├── results_display_wiring.py
│ │ │ ├── results_display_wiring_test.py
│ │ │ ├── training_dataset_builder_wiring.py
│ │ │ ├── training_dataset_preprocess_wiring.py
│ │ │ ├── training_lokr_wiring.py
│ │ │ └── training_run_wiring.py
│ │ ├── help_content.py
│ │ ├── help_content_i18n_test.py
│ │ ├── help_content_md_test.py
│ │ ├── help_content_misc_test.py
│ │ ├── help_content_test.py
│ │ ├── help_content_test_helpers.py
│ │ ├── i18n/
│ │ │ ├── __init__.py
│ │ │ ├── en.json
│ │ │ ├── he.json
│ │ │ ├── i18n.py
│ │ │ ├── i18n_thread_safety_test.py
│ │ │ ├── ja.json
│ │ │ └── zh.json
│ │ └── interfaces/
│ │ ├── __init__.py
│ │ ├── audio_player_preferences.js
│ │ ├── audio_player_preferences.py
│ │ ├── audio_player_preferences_test.py
│ │ ├── dataset.py
│ │ ├── generation.py
│ │ ├── generation_advanced_dit_controls.py
│ │ ├── generation_advanced_output_controls.py
│ │ ├── generation_advanced_primary_controls.py
│ │ ├── generation_advanced_settings.py
│ │ ├── generation_contract_ast_utils.py
│ │ ├── generation_decomposition_contract_test.py
│ │ ├── generation_defaults.py
│ │ ├── generation_service_config.py
│ │ ├── generation_service_config_rows.py
│ │ ├── generation_service_config_rows_test.py
│ │ ├── generation_service_config_toggles.py
│ │ ├── generation_tab_generate_controls.py
│ │ ├── generation_tab_optional_controls.py
│ │ ├── generation_tab_optional_controls_test.py
│ │ ├── generation_tab_primary_controls.py
│ │ ├── generation_tab_runtime_controls.py
│ │ ├── generation_tab_secondary_controls.py
│ │ ├── generation_tab_section.py
│ │ ├── generation_tab_simple_controls.py
│ │ ├── generation_tab_source_controls.py
│ │ ├── result.py
│ │ ├── training.py
│ │ ├── training_contract_ast_utils.py
│ │ ├── training_dataset_builder_tab.py
│ │ ├── training_dataset_tab_label_preview.py
│ │ ├── training_dataset_tab_save_preprocess.py
│ │ ├── training_dataset_tab_scan_settings.py
│ │ ├── training_decomposition_contract_test.py
│ │ ├── training_lokr_tab.py
│ │ ├── training_lokr_tab_dataset.py
│ │ ├── training_lokr_tab_run_export.py
│ │ ├── training_lora_tab.py
│ │ ├── training_lora_tab_dataset.py
│ │ └── training_lora_tab_run_export.py
│ └── streamlit/
│ ├── .gitignore
│ ├── .streamlit/
│ │ ├── config.toml
│ │ └── secrets.toml
│ ├── INSTALL.md
│ ├── PROJECT_SUMMARY.md
│ ├── QUICKSTART.md
│ ├── README.md
│ ├── components/
│ │ ├── __init__.py
│ │ ├── audio_player.py
│ │ ├── batch_generator.py
│ │ ├── dashboard.py
│ │ ├── editor.py
│ │ ├── editor_audio_picker.py
│ │ ├── editor_runner.py
│ │ ├── editor_tasks.py
│ │ ├── editor_waveform.py
│ │ ├── generation_wizard.py
│ │ └── settings_panel.py
│ ├── config.py
│ ├── main.py
│ ├── requirements.txt
│ ├── run.bat
│ ├── run.sh
│ └── utils/
│ ├── __init__.py
│ ├── audio_utils.py
│ ├── cache.py
│ └── project_manager.py
├── check_update.bat
├── check_update.sh
├── cli.py
├── close_api_server.sh
├── docker-compose.jetson.yml
├── docs/
│ ├── .vitepress/
│ │ ├── config.mts
│ │ └── theme/
│ │ ├── custom.css
│ │ └── index.ts
│ ├── en/
│ │ ├── ACE-Step1.5-Rocm-Manual-Linux.md
│ │ ├── API.md
│ │ ├── BENCHMARK.md
│ │ ├── CLI.md
│ │ ├── GPU_COMPATIBILITY.md
│ │ ├── GPU_TROUBLESHOOTING.md
│ │ ├── GRADIO_GUIDE.md
│ │ ├── INFERENCE.md
│ │ ├── INSTALL.md
│ │ ├── LoRA_Training_Tutorial.md
│ │ ├── Openrouter_API_DOC.md
│ │ ├── Tutorial.md
│ │ ├── VST3_BACKEND_CONTRACT.md
│ │ ├── VST3_MVP.md
│ │ ├── VST3_SETUP.md
│ │ ├── ace_step_musicians_guide.md
│ │ ├── index.md
│ │ └── studio.md
│ ├── index.md
│ ├── ja/
│ │ ├── API.md
│ │ ├── GPU_COMPATIBILITY.md
│ │ ├── GRADIO_GUIDE.md
│ │ ├── INFERENCE.md
│ │ ├── INSTALL.md
│ │ ├── LoRA_Training_Tutorial.md
│ │ ├── Openrouter_API_DOC.md
│ │ ├── Tutorial.md
│ │ └── index.md
│ ├── ko/
│ │ ├── API.md
│ │ ├── GPU_COMPATIBILITY.md
│ │ ├── GRADIO_GUIDE.md
│ │ ├── INFERENCE.md
│ │ ├── LoRA_Training_Tutorial.md
│ │ ├── Openrouter_API_DOC.md
│ │ ├── Tutorial.md
│ │ └── index.md
│ ├── sidestep/
│ │ ├── Dataset Preparation.md
│ │ ├── End-to-End Tutorial.md
│ │ ├── Estimation Guide.md
│ │ ├── Getting Started.md
│ │ ├── Model Management.md
│ │ ├── ObsidianREADME.md
│ │ ├── Preset Management.md
│ │ ├── RepositoryREADME.md
│ │ ├── Shift and Timestep Sampling.md
│ │ ├── The Settings Wizard.md
│ │ ├── Training Guide.md
│ │ ├── Using Your Adapter.md
│ │ ├── VRAM Optimization Guide.md
│ │ └── Windows Notes.md
│ └── zh/
│ ├── API.md
│ ├── BENCHMARK.md
│ ├── GPU_COMPATIBILITY.md
│ ├── GRADIO_GUIDE.md
│ ├── INFERENCE.md
│ ├── INSTALL.md
│ ├── LoRA_Training_Tutorial.md
│ ├── Openrouter_API_DOC.md
│ ├── Tutorial.md
│ └── index.md
├── examples/
│ ├── simple_mode/
│ │ ├── example_01.json
│ │ ├── example_02.json
│ │ ├── example_03.json
│ │ ├── example_04.json
│ │ ├── example_05.json
│ │ ├── example_06.json
│ │ ├── example_07.json
│ │ ├── example_08.json
│ │ ├── example_09.json
│ │ ├── example_10.json
│ │ ├── example_100.json
│ │ ├── example_101.json
│ │ ├── example_102.json
│ │ ├── example_103.json
│ │ ├── example_104.json
│ │ ├── example_105.json
│ │ ├── example_106.json
│ │ ├── example_107.json
│ │ ├── example_108.json
│ │ ├── example_109.json
│ │ ├── example_11.json
│ │ ├── example_110.json
│ │ ├── example_111.json
│ │ ├── example_112.json
│ │ ├── example_113.json
│ │ ├── example_114.json
│ │ ├── example_115.json
│ │ ├── example_116.json
│ │ ├── example_117.json
│ │ ├── example_118.json
│ │ ├── example_119.json
│ │ ├── example_12.json
│ │ ├── example_120.json
│ │ ├── example_121.json
│ │ ├── example_122.json
│ │ ├── example_123.json
│ │ ├── example_124.json
│ │ ├── example_125.json
│ │ ├── example_126.json
│ │ ├── example_127.json
│ │ ├── example_128.json
│ │ ├── example_129.json
│ │ ├── example_13.json
│ │ ├── example_130.json
│ │ ├── example_131.json
│ │ ├── example_132.json
│ │ ├── example_133.json
│ │ ├── example_134.json
│ │ ├── example_135.json
│ │ ├── example_136.json
│ │ ├── example_137.json
│ │ ├── example_138.json
│ │ ├── example_139.json
│ │ ├── example_14.json
│ │ ├── example_140.json
│ │ ├── example_141.json
│ │ ├── example_142.json
│ │ ├── example_143.json
│ │ ├── example_144.json
│ │ ├── example_145.json
│ │ ├── example_146.json
│ │ ├── example_147.json
│ │ ├── example_148.json
│ │ ├── example_149.json
│ │ ├── example_15.json
│ │ ├── example_150.json
│ │ ├── example_151.json
│ │ ├── example_152.json
│ │ ├── example_153.json
│ │ ├── example_154.json
│ │ ├── example_155.json
│ │ ├── example_156.json
│ │ ├── example_157.json
│ │ ├── example_158.json
│ │ ├── example_159.json
│ │ ├── example_16.json
│ │ ├── example_160.json
│ │ ├── example_161.json
│ │ ├── example_162.json
│ │ ├── example_163.json
│ │ ├── example_164.json
│ │ ├── example_165.json
│ │ ├── example_166.json
│ │ ├── example_167.json
│ │ ├── example_168.json
│ │ ├── example_169.json
│ │ ├── example_17.json
│ │ ├── example_170.json
│ │ ├── example_171.json
│ │ ├── example_172.json
│ │ ├── example_173.json
│ │ ├── example_174.json
│ │ ├── example_175.json
│ │ ├── example_176.json
│ │ ├── example_177.json
│ │ ├── example_178.json
│ │ ├── example_179.json
│ │ ├── example_18.json
│ │ ├── example_180.json
│ │ ├── example_181.json
│ │ ├── example_182.json
│ │ ├── example_183.json
│ │ ├── example_184.json
│ │ ├── example_185.json
│ │ ├── example_186.json
│ │ ├── example_187.json
│ │ ├── example_188.json
│ │ ├── example_189.json
│ │ ├── example_19.json
│ │ ├── example_190.json
│ │ ├── example_191.json
│ │ ├── example_192.json
│ │ ├── example_193.json
│ │ ├── example_194.json
│ │ ├── example_195.json
│ │ ├── example_196.json
│ │ ├── example_197.json
│ │ ├── example_198.json
│ │ ├── example_199.json
│ │ ├── example_20.json
│ │ ├── example_200.json
│ │ ├── example_21.json
│ │ ├── example_22.json
│ │ ├── example_23.json
│ │ ├── example_24.json
│ │ ├── example_25.json
│ │ ├── example_26.json
│ │ ├── example_27.json
│ │ ├── example_28.json
│ │ ├── example_29.json
│ │ ├── example_30.json
│ │ ├── example_31.json
│ │ ├── example_32.json
│ │ ├── example_33.json
│ │ ├── example_34.json
│ │ ├── example_35.json
│ │ ├── example_36.json
│ │ ├── example_37.json
│ │ ├── example_38.json
│ │ ├── example_39.json
│ │ ├── example_40.json
│ │ ├── example_41.json
│ │ ├── example_42.json
│ │ ├── example_43.json
│ │ ├── example_44.json
│ │ ├── example_45.json
│ │ ├── example_46.json
│ │ ├── example_47.json
│ │ ├── example_48.json
│ │ ├── example_49.json
│ │ ├── example_50.json
│ │ ├── example_51.json
│ │ ├── example_52.json
│ │ ├── example_53.json
│ │ ├── example_54.json
│ │ ├── example_55.json
│ │ ├── example_56.json
│ │ ├── example_57.json
│ │ ├── example_58.json
│ │ ├── example_59.json
│ │ ├── example_60.json
│ │ ├── example_61.json
│ │ ├── example_62.json
│ │ ├── example_63.json
│ │ ├── example_64.json
│ │ ├── example_65.json
│ │ ├── example_66.json
│ │ ├── example_67.json
│ │ ├── example_68.json
│ │ ├── example_69.json
│ │ ├── example_70.json
│ │ ├── example_71.json
│ │ ├── example_72.json
│ │ ├── example_73.json
│ │ ├── example_74.json
│ │ ├── example_75.json
│ │ ├── example_76.json
│ │ ├── example_77.json
│ │ ├── example_78.json
│ │ ├── example_79.json
│ │ ├── example_80.json
│ │ ├── example_81.json
│ │ ├── example_82.json
│ │ ├── example_83.json
│ │ ├── example_84.json
│ │ ├── example_85.json
│ │ ├── example_86.json
│ │ ├── example_87.json
│ │ ├── example_88.json
│ │ ├── example_89.json
│ │ ├── example_90.json
│ │ ├── example_91.json
│ │ ├── example_92.json
│ │ ├── example_93.json
│ │ ├── example_94.json
│ │ ├── example_95.json
│ │ ├── example_96.json
│ │ ├── example_97.json
│ │ ├── example_98.json
│ │ └── example_99.json
│ └── text2music/
│ ├── example_01.json
│ ├── example_02.json
│ ├── example_03.json
│ ├── example_04.json
│ ├── example_05.json
│ ├── example_06.json
│ ├── example_07.json
│ ├── example_08.json
│ ├── example_09.json
│ ├── example_10.json
│ ├── example_100.json
│ ├── example_101.json
│ ├── example_102.json
│ ├── example_103.json
│ ├── example_104.json
│ ├── example_105.json
│ ├── example_106.json
│ ├── example_107.json
│ ├── example_108.json
│ ├── example_109.json
│ ├── example_11.json
│ ├── example_110.json
│ ├── example_111.json
│ ├── example_112.json
│ ├── example_113.json
│ ├── example_114.json
│ ├── example_115.json
│ ├── example_116.json
│ ├── example_117.json
│ ├── example_118.json
│ ├── example_119.json
│ ├── example_12.json
│ ├── example_120.json
│ ├── example_121.json
│ ├── example_122.json
│ ├── example_123.json
│ ├── example_124.json
│ ├── example_125.json
│ ├── example_126.json
│ ├── example_127.json
│ ├── example_128.json
│ ├── example_129.json
│ ├── example_13.json
│ ├── example_130.json
│ ├── example_131.json
│ ├── example_132.json
│ ├── example_133.json
│ ├── example_134.json
│ ├── example_135.json
│ ├── example_136.json
│ ├── example_137.json
│ ├── example_138.json
│ ├── example_139.json
│ ├── example_14.json
│ ├── example_140.json
│ ├── example_141.json
│ ├── example_142.json
│ ├── example_143.json
│ ├── example_144.json
│ ├── example_145.json
│ ├── example_146.json
│ ├── example_147.json
│ ├── example_148.json
│ ├── example_149.json
│ ├── example_15.json
│ ├── example_150.json
│ ├── example_151.json
│ ├── example_152.json
│ ├── example_153.json
│ ├── example_154.json
│ ├── example_155.json
│ ├── example_156.json
│ ├── example_157.json
│ ├── example_158.json
│ ├── example_159.json
│ ├── example_16.json
│ ├── example_160.json
│ ├── example_161.json
│ ├── example_162.json
│ ├── example_163.json
│ ├── example_164.json
│ ├── example_165.json
│ ├── example_166.json
│ ├── example_167.json
│ ├── example_168.json
│ ├── example_169.json
│ ├── example_17.json
│ ├── example_170.json
│ ├── example_171.json
│ ├── example_172.json
│ ├── example_173.json
│ ├── example_174.json
│ ├── example_175.json
│ ├── example_176.json
│ ├── example_177.json
│ ├── example_178.json
│ ├── example_179.json
│ ├── example_18.json
│ ├── example_180.json
│ ├── example_181.json
│ ├── example_182.json
│ ├── example_183.json
│ ├── example_184.json
│ ├── example_185.json
│ ├── example_186.json
│ ├── example_187.json
│ ├── example_188.json
│ ├── example_189.json
│ ├── example_19.json
│ ├── example_190.json
│ ├── example_191.json
│ ├── example_192.json
│ ├── example_193.json
│ ├── example_194.json
│ ├── example_195.json
│ ├── example_196.json
│ ├── example_197.json
│ ├── example_198.json
│ ├── example_199.json
│ ├── example_20.json
│ ├── example_200.json
│ ├── example_21.json
│ ├── example_22.json
│ ├── example_23.json
│ ├── example_24.json
│ ├── example_25.json
│ ├── example_26.json
│ ├── example_27.json
│ ├── example_28.json
│ ├── example_29.json
│ ├── example_30.json
│ ├── example_31.json
│ ├── example_32.json
│ ├── example_33.json
│ ├── example_34.json
│ ├── example_35.json
│ ├── example_36.json
│ ├── example_37.json
│ ├── example_38.json
│ ├── example_39.json
│ ├── example_40.json
│ ├── example_41.json
│ ├── example_42.json
│ ├── example_43.json
│ ├── example_44.json
│ ├── example_45.json
│ ├── example_46.json
│ ├── example_47.json
│ ├── example_48.json
│ ├── example_49.json
│ ├── example_50.json
│ ├── example_51.json
│ ├── example_52.json
│ ├── example_53.json
│ ├── example_54.json
│ ├── example_55.json
│ ├── example_56.json
│ ├── example_57.json
│ ├── example_58.json
│ ├── example_59.json
│ ├── example_60.json
│ ├── example_61.json
│ ├── example_62.json
│ ├── example_63.json
│ ├── example_64.json
│ ├── example_65.json
│ ├── example_66.json
│ ├── example_67.json
│ ├── example_68.json
│ ├── example_69.json
│ ├── example_70.json
│ ├── example_71.json
│ ├── example_72.json
│ ├── example_73.json
│ ├── example_74.json
│ ├── example_75.json
│ ├── example_76.json
│ ├── example_77.json
│ ├── example_78.json
│ ├── example_79.json
│ ├── example_80.json
│ ├── example_81.json
│ ├── example_82.json
│ ├── example_83.json
│ ├── example_84.json
│ ├── example_85.json
│ ├── example_86.json
│ ├── example_87.json
│ ├── example_88.json
│ ├── example_89.json
│ ├── example_90.json
│ ├── example_91.json
│ ├── example_92.json
│ ├── example_93.json
│ ├── example_94.json
│ ├── example_95.json
│ ├── example_96.json
│ ├── example_97.json
│ ├── example_98.json
│ └── example_99.json
├── generate_examples.py
├── install_uv.bat
├── install_uv.sh
├── merge_config.bat
├── merge_config.sh
├── openrouter/
│ ├── __init__.py
│ ├── client_test.py
│ ├── openrouter_api_server.py
│ └── stress_test.py
├── package.json
├── plugins/
│ └── acestep_vst3/
│ ├── CMakeLists.txt
│ ├── README.md
│ └── src/
│ ├── PluginBackendClient.cpp
│ ├── PluginBackendClient.h
│ ├── PluginConfig.h
│ ├── PluginEditor.cpp
│ ├── PluginEditor.h
│ ├── PluginEditorPreview.cpp
│ ├── PluginEditorState.cpp
│ ├── PluginEnums.cpp
│ ├── PluginEnums.h
│ ├── PluginMockGeneration.cpp
│ ├── PluginMockGeneration.h
│ ├── PluginPreview.cpp
│ ├── PluginPreview.h
│ ├── PluginProcessor.cpp
│ ├── PluginProcessor.h
│ ├── PluginState.cpp
│ └── PluginState.h
├── profile_inference.py
├── proxy_config.txt.example
├── pyproject.toml
├── quick_test.bat
├── quick_test.sh
├── requirements-rocm-linux.txt
├── requirements-rocm.txt
├── requirements-sidestep.txt
├── requirements-xpu.txt
├── requirements.txt
├── run_api_server.sh
├── run_openrouter_api_server.sh
├── scripts/
│ ├── check_gpu.py
│ ├── fetch-awesome.mjs
│ ├── lora_data_prepare/
│ │ ├── elevenlabs_transcription.py
│ │ ├── gemini_caption.py
│ │ └── whisper_transcription.py
│ ├── new_pr_branch.ps1
│ ├── prepare_vae_calibration_data.py
│ └── profile_vram.py
├── setup_xpu.bat
├── start_api_server.bat
├── start_api_server.sh
├── start_api_server_macos.sh
├── start_api_server_rocm.bat
├── start_api_server_rocm.sh
├── start_api_server_xpu.bat
├── start_gradio_ui.bat
├── start_gradio_ui.sh
├── start_gradio_ui_macos.sh
├── start_gradio_ui_macos_manual.sh
├── start_gradio_ui_manual.bat
├── start_gradio_ui_manual.sh
├── start_gradio_ui_rocm.bat
├── start_gradio_ui_rocm.sh
├── start_gradio_ui_rocm_manual.bat
├── start_gradio_ui_rocm_manual.sh
├── start_gradio_ui_xpu.bat
├── start_gradio_ui_xpu_manual.bat
├── test_env_detection.bat
├── test_env_detection.sh
├── test_git_update.bat
├── test_git_update.sh
├── train.py
└── ui/
├── studio.html
└── studio_html_test.py
Showing preview only (368K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3678 symbols across 512 files)
FILE: .claude/skills/acestep-simplemv/scripts/render.mjs
function resolveFilePath (line 33) | function resolveFilePath(p) {
function findBrowserExecutable (line 58) | function findBrowserExecutable(cliOverride) {
function isHeadlessShell (line 146) | function isHeadlessShell(exePath) {
function parseLrc (line 151) | function parseLrc(content) {
function getAudioDuration (line 176) | function getAudioDuration(filePath) {
function parseArgs (line 188) | function parseArgs(argv) {
FILE: .claude/skills/acestep-simplemv/scripts/src/parseLrc.ts
function parseLrc (line 11) | function parseLrc(lrcContent: string): LyricLine[] {
FILE: .claude/skills/acestep-simplemv/scripts/src/types.ts
type LyricLine (line 1) | interface LyricLine {
type MVInputProps (line 7) | interface MVInputProps extends Record<string, unknown> {
FILE: acestep/acestep_v15_pipeline.py
function create_demo (line 85) | def create_demo(init_params=None, language="en"):
function main (line 128) | def main():
FILE: acestep/api/http/audio_route.py
function register_audio_route (line 11) | def register_audio_route(
FILE: acestep/api/http/audio_route_http_test.py
function _verify_api_key (line 14) | async def _verify_api_key(authorization: str | None = Header(None)) -> N...
class AudioRouteHttpTests (line 21) | class AudioRouteHttpTests(unittest.TestCase):
method test_requires_authentication (line 24) | def test_requires_authentication(self):
method test_serves_audio_file_with_authorization (line 34) | def test_serves_audio_file_with_authorization(self):
FILE: acestep/api/http/audio_route_test.py
function _verify_api_key (line 13) | async def _verify_api_key(_authorization: str | None = None) -> None:
function _get_endpoint (line 19) | def _get_endpoint(app: FastAPI, path: str, method: str):
class AudioRouteTests (line 28) | class AudioRouteTests(unittest.TestCase):
method test_rejects_path_outside_allowed_dir (line 31) | def test_rejects_path_outside_allowed_dir(self):
method test_returns_404_when_file_missing (line 46) | def test_returns_404_when_file_missing(self):
method test_returns_404_for_directory_target (line 60) | def test_returns_404_for_directory_target(self):
FILE: acestep/api/http/auth.py
function set_api_key (line 12) | def set_api_key(key: Optional[str]) -> None:
function verify_token_from_request (line 23) | def verify_token_from_request(
function verify_api_key (line 57) | async def verify_api_key(authorization: Optional[str] = Header(None)) ->...
FILE: acestep/api/http/auth_test.py
class AuthHelpersTests (line 13) | class AuthHelpersTests(unittest.TestCase):
method setUp (line 16) | def setUp(self) -> None:
method tearDown (line 21) | def tearDown(self) -> None:
method test_verify_token_returns_none_when_auth_is_disabled (line 26) | def test_verify_token_returns_none_when_auth_is_disabled(self) -> None:
method test_verify_token_accepts_ai_token_in_body (line 33) | def test_verify_token_accepts_ai_token_in_body(self) -> None:
method test_verify_token_rejects_invalid_ai_token (line 40) | def test_verify_token_rejects_invalid_ai_token(self) -> None:
method test_verify_token_accepts_bearer_header (line 49) | def test_verify_token_accepts_bearer_header(self) -> None:
method test_verify_token_requires_token_when_auth_enabled (line 56) | def test_verify_token_requires_token_when_auth_enabled(self) -> None:
method test_verify_api_key_rejects_invalid_or_missing_header (line 65) | def test_verify_api_key_rejects_invalid_or_missing_header(self) -> None:
FILE: acestep/api/http/lora_routes.py
class LoadLoRARequest (line 16) | class LoadLoRARequest(BaseModel):
class SetLoRAScaleRequest (line 23) | class SetLoRAScaleRequest(BaseModel):
class ToggleLoRARequest (line 30) | class ToggleLoRARequest(BaseModel):
function _require_initialized_handler (line 36) | def _require_initialized_handler(app: FastAPI) -> AceStepHandler:
function _is_success_message (line 45) | def _is_success_message(result: str, allow_warning: bool = False) -> bool:
function register_lora_routes (line 53) | def register_lora_routes(
FILE: acestep/api/http/lora_routes_http_test.py
function _wrap_response (line 12) | def _wrap_response(data: Any, code: int = 200, error: str | None = None)...
function _verify_api_key (line 18) | async def _verify_api_key(authorization: str | None = Header(None)) -> N...
class _FakeHandler (line 25) | class _FakeHandler:
method __init__ (line 28) | def __init__(self, model: object | None = None) -> None:
method add_lora (line 33) | def add_lora(self, lora_path: str, adapter_name: str | None = None) ->...
method load_lora (line 39) | def load_lora(self, lora_path: str) -> str:
method unload_lora (line 45) | def unload_lora(self) -> str:
method set_use_lora (line 51) | def set_use_lora(self, use_lora: bool) -> str:
method set_lora_scale (line 57) | def set_lora_scale(self, *args) -> str:
method get_lora_status (line 63) | def get_lora_status(self) -> Dict[str, Any]:
class LoraRoutesHttpTests (line 70) | class LoraRoutesHttpTests(unittest.TestCase):
method _build_client (line 73) | def _build_client(self, handler: _FakeHandler) -> TestClient:
method test_load_lora_post_returns_wrapped_success_payload (line 81) | def test_load_lora_post_returns_wrapped_success_payload(self):
method test_toggle_lora_post_preserves_wrapper_400_semantics (line 99) | def test_toggle_lora_post_preserves_wrapper_400_semantics(self):
method test_status_get_returns_http_500_when_model_not_initialized (line 117) | def test_status_get_returns_http_500_when_model_not_initialized(self):
method test_requests_require_authorization_header (line 128) | def test_requests_require_authorization_header(self):
FILE: acestep/api/http/lora_routes_test.py
function _wrap_response (line 18) | def _wrap_response(data: Any, code: int = 200, error: str | None = None)...
function _verify_api_key (line 24) | async def _verify_api_key(_: str | None = None) -> None:
function _get_route_endpoint (line 30) | def _get_route_endpoint(app: FastAPI, path: str, method: str):
class _FakeHandler (line 40) | class _FakeHandler:
method __init__ (line 43) | def __init__(self, model: object | None = None) -> None:
method add_lora (line 52) | def add_lora(self, lora_path: str, adapter_name: str | None = None) ->...
method load_lora (line 56) | def load_lora(self, lora_path: str) -> str:
method unload_lora (line 60) | def unload_lora(self) -> str:
method set_use_lora (line 64) | def set_use_lora(self, use_lora: bool) -> str:
method set_lora_scale (line 68) | def set_lora_scale(self, *args) -> str:
method get_lora_status (line 72) | def get_lora_status(self) -> Dict[str, Any]:
class LoraRoutesTests (line 77) | class LoraRoutesTests(unittest.TestCase):
method _build_app (line 80) | def _build_app(self, handler: _FakeHandler) -> FastAPI:
method test_load_route_uses_add_lora_when_adapter_name_present (line 88) | def test_load_route_uses_add_lora_when_adapter_name_present(self):
method test_status_route_raises_when_model_not_initialized (line 102) | def test_status_route_raises_when_model_not_initialized(self):
method test_scale_route_accepts_warning_prefix_as_success (line 115) | def test_scale_route_accepts_warning_prefix_as_success(self):
method test_toggle_route_returns_400_wrapper_for_non_success_message (line 129) | def test_toggle_route_returns_400_wrapper_for_non_success_message(self):
FILE: acestep/api/http/model_init_service.py
function initialize_models_for_request (line 11) | def initialize_models_for_request(
FILE: acestep/api/http/model_init_service_test.py
class _FakeHandler (line 11) | class _FakeHandler:
method initialize_service (line 14) | def initialize_service(self, **_kwargs):
class _FakeLlm (line 20) | class _FakeLlm:
method initialize (line 23) | def initialize(self, **_kwargs):
class _FailingLlm (line 29) | class _FailingLlm:
method initialize (line 32) | def initialize(self, **_kwargs):
class ModelInitServiceTests (line 38) | class ModelInitServiceTests(unittest.TestCase):
method test_raises_when_handler_missing (line 41) | def test_raises_when_handler_missing(self):
method test_raises_when_init_llm_requested_but_llm_missing (line 59) | def test_raises_when_init_llm_requested_but_llm_missing(self):
method test_returns_loaded_model_when_dit_init_succeeds (line 77) | def test_returns_loaded_model_when_dit_init_succeeds(self):
method test_lm_init_failure_sets_state_and_raises (line 101) | def test_lm_init_failure_sets_state_and_raises(self):
FILE: acestep/api/http/model_service_routes.py
class InitModelRequest (line 17) | class InitModelRequest(BaseModel):
function _read_model_supported_tasks (line 25) | def _read_model_supported_tasks(checkpoint_dir: str, model_name: str) ->...
function _collect_model_inventory (line 41) | def _collect_model_inventory(
function register_model_service_routes (line 120) | def register_model_service_routes(
FILE: acestep/api/http/model_service_routes_http_test.py
function _wrap_response (line 16) | def _wrap_response(data, code=200, error=None):
function _verify_api_key (line 22) | async def _verify_api_key(authorization: str | None = Header(None)) -> N...
class _FakeStore (line 29) | class _FakeStore:
method get_stats (line 32) | def get_stats(self):
class _FakeHandler (line 38) | class _FakeHandler:
method initialize_service (line 41) | def initialize_service(self, **_kwargs):
class _FakeLlm (line 47) | class _FakeLlm:
method initialize (line 52) | def initialize(self, **_kwargs):
class _FailingLlm (line 58) | class _FailingLlm:
method initialize (line 63) | def initialize(self, **_kwargs):
class ModelServiceRoutesHttpTests (line 69) | class ModelServiceRoutesHttpTests(unittest.TestCase):
method _build_client (line 72) | def _build_client(self, llm_handler=None) -> TestClient:
method test_stats_requires_authentication (line 107) | def test_stats_requires_authentication(self):
method test_models_requires_authentication (line 114) | def test_models_requires_authentication(self):
method test_model_inventory_requires_authentication (line 121) | def test_model_inventory_requires_authentication(self):
method test_init_requires_authentication (line 128) | def test_init_requires_authentication(self):
method test_health_returns_wrapped_payload (line 135) | def test_health_returns_wrapped_payload(self):
method test_init_route_returns_wrapped_success (line 145) | def test_init_route_returns_wrapped_success(self):
method test_init_route_returns_wrapped_error_when_initializer_fails (line 164) | def test_init_route_returns_wrapped_error_when_initializer_fails(self):
method test_init_route_returns_wrapped_error_when_llm_init_fails (line 183) | def test_init_route_returns_wrapped_error_when_llm_init_fails(self):
FILE: acestep/api/http/model_service_routes_test.py
function _wrap_response (line 20) | def _wrap_response(data, code=200, error=None):
function _verify_api_key (line 26) | async def _verify_api_key(_: str | None = None) -> None:
function _get_endpoint (line 32) | def _get_endpoint(app: FastAPI, path: str, method: str):
class _FakeStore (line 41) | class _FakeStore:
method get_stats (line 44) | def get_stats(self):
class ModelServiceRoutesTests (line 50) | class ModelServiceRoutesTests(unittest.TestCase):
method _build_app (line 53) | def _build_app(self) -> FastAPI:
method test_collect_model_inventory_merges_loaded_and_available_models (line 87) | def test_collect_model_inventory_merges_loaded_and_available_models(se...
method test_init_route_wraps_initializer_exception (line 107) | def test_init_route_wraps_initializer_exception(self):
FILE: acestep/api/http/query_result_route.py
function register_query_result_route (line 12) | def register_query_result_route(
FILE: acestep/api/http/query_result_route_http_test.py
function _wrap_response (line 14) | def _wrap_response(data, code=200, error=None):
function _verify_token_from_request (line 26) | def _verify_token_from_request(body: dict, authorization: str | None = N...
function _map_status (line 36) | def _map_status(status: str) -> int:
class _FakeStore (line 42) | class _FakeStore:
method __init__ (line 45) | def __init__(self, records: dict[str, object]) -> None:
method get (line 50) | def get(self, task_id: str):
class QueryResultRouteHttpTests (line 56) | class QueryResultRouteHttpTests(unittest.TestCase):
method _build_client (line 59) | def _build_client(self, records: dict[str, object] | None = None, loca...
method test_query_result_requires_auth (line 76) | def test_query_result_requires_auth(self):
method test_query_result_marks_timed_out_cache_entry_as_failed (line 83) | def test_query_result_marks_timed_out_cache_entry_as_failed(self):
method test_query_result_returns_full_analysis_result_directly (line 98) | def test_query_result_returns_full_analysis_result_directly(self):
method test_query_result_returns_extract_codes_result_directly (line 119) | def test_query_result_returns_extract_codes_result_directly(self):
method test_query_result_accepts_form_encoded_payload (line 157) | def test_query_result_accepts_form_encoded_payload(self):
method test_query_result_returns_empty_data_for_missing_task_id_list (line 182) | def test_query_result_returns_empty_data_for_missing_task_id_list(self):
method test_query_result_returns_empty_data_for_malformed_task_id_list (line 191) | def test_query_result_returns_empty_data_for_malformed_task_id_list(se...
method test_query_result_preserves_non_list_json_task_id_iteration (line 203) | def test_query_result_preserves_non_list_json_task_id_iteration(self):
FILE: acestep/api/http/query_result_route_test.py
function _wrap_response (line 15) | def _wrap_response(data, code=200, error=None):
function _verify_token_from_request (line 27) | def _verify_token_from_request(body: dict, authorization: str | None = N...
function _map_status (line 37) | def _map_status(status: str) -> int:
function _get_endpoint (line 43) | def _get_endpoint(app: FastAPI, path: str, method: str):
class _FakeStore (line 52) | class _FakeStore:
method __init__ (line 55) | def __init__(self, records: dict[str, object]) -> None:
method get (line 60) | def get(self, task_id: str):
class QueryResultRouteTests (line 66) | class QueryResultRouteTests(unittest.TestCase):
method _build_app (line 69) | def _build_app(self, records: dict[str, object] | None = None, local_c...
method test_query_result_uses_cache_payload_when_present (line 86) | def test_query_result_uses_cache_payload_when_present(self):
method test_query_result_uses_store_payload_when_cache_missing (line 106) | def test_query_result_uses_store_payload_when_cache_missing(self):
method test_query_result_returns_empty_when_task_missing (line 138) | def test_query_result_returns_empty_when_task_missing(self):
method test_query_result_falls_back_when_cache_json_is_non_list (line 154) | def test_query_result_falls_back_when_cache_json_is_non_list(self):
FILE: acestep/api/http/query_result_service.py
function parse_task_id_list (line 10) | def parse_task_id_list(task_id_list_raw: Any) -> Any:
function _build_running_result_payload (line 29) | def _build_running_result_payload(
function _build_store_result_payload (line 63) | def _build_store_result_payload(
function collect_query_results (line 142) | def collect_query_results(
FILE: acestep/api/http/reinitialize_route.py
function register_reinitialize_route (line 12) | def register_reinitialize_route(
FILE: acestep/api/http/reinitialize_route_http_test.py
function _wrap_response (line 16) | def _wrap_response(data, code=200, error=None):
function _verify_api_key (line 22) | async def _verify_api_key(authorization: str | None = Header(None)) -> N...
class ReinitializeRouteHttpTests (line 29) | class ReinitializeRouteHttpTests(unittest.TestCase):
method _build_client (line 32) | def _build_client(self, handler) -> TestClient:
method test_missing_handler_returns_raw_http_500_contract (line 47) | def test_missing_handler_returns_raw_http_500_contract(self):
method test_requires_authentication (line 67) | def test_requires_authentication(self):
method test_returns_wrapped_success_payload (line 75) | def test_returns_wrapped_success_payload(self):
FILE: acestep/api/http/reinitialize_route_test.py
function _wrap_response (line 14) | def _wrap_response(data, code=200, error=None):
function _verify_api_key (line 20) | async def _verify_api_key(_: str | None = None) -> None:
function _get_endpoint (line 26) | def _get_endpoint(app: FastAPI, path: str, method: str):
class ReinitializeRouteUnitTests (line 35) | class ReinitializeRouteUnitTests(unittest.TestCase):
method test_raises_http_500_when_service_not_initialized (line 38) | def test_raises_http_500_when_service_not_initialized(self):
method test_missing_llm_handler_returns_wrapped_success (line 58) | def test_missing_llm_handler_returns_wrapped_success(self):
method test_returns_wrapped_success_when_no_reload_needed (line 80) | def test_returns_wrapped_success_when_no_reload_needed(self):
method test_handler_reload_failure_keeps_wrapped_success_contract (line 107) | def test_handler_reload_failure_keeps_wrapped_success_contract(self):
FILE: acestep/api/http/release_task_audio_paths.py
function validate_audio_path (line 14) | def validate_audio_path(path: Optional[str]) -> Optional[str]:
function save_upload_to_temp (line 49) | async def save_upload_to_temp(upload: StarletteUploadFile, *, prefix: st...
FILE: acestep/api/http/release_task_audio_paths_test.py
class _FakeUpload (line 14) | class _FakeUpload:
method __init__ (line 17) | def __init__(self, payload: bytes, filename: str = "clip.wav") -> None:
method read (line 25) | async def read(self, size: int) -> bytes:
method close (line 35) | async def close(self) -> None:
class ReleaseTaskAudioPathsTests (line 41) | class ReleaseTaskAudioPathsTests(unittest.TestCase):
method test_validate_audio_path_rejects_absolute_non_temp_path (line 44) | def test_validate_audio_path_rejects_absolute_non_temp_path(self):
method test_validate_audio_path_rejects_traversal_sequences (line 52) | def test_validate_audio_path_rejects_traversal_sequences(self):
method test_save_upload_to_temp_cleans_up_on_fd_close_failure (line 60) | def test_save_upload_to_temp_cleans_up_on_fd_close_failure(self):
method test_save_upload_to_temp_writes_file_and_closes_upload (line 81) | def test_save_upload_to_temp_writes_file_and_closes_upload(self):
FILE: acestep/api/http/release_task_models.py
class GenerateMusicRequest (line 12) | class GenerateMusicRequest(BaseModel):
class Config (line 127) | class Config:
FILE: acestep/api/http/release_task_models_test.py
class ReleaseTaskModelsTests (line 9) | class ReleaseTaskModelsTests(unittest.TestCase):
method test_generate_music_request_preserves_legacy_defaults (line 12) | def test_generate_music_request_preserves_legacy_defaults(self):
method test_new_fields_have_expected_defaults (line 22) | def test_new_fields_have_expected_defaults(self):
method test_audio_code_string_and_cover_noise_strength_are_accepted (line 29) | def test_audio_code_string_and_cover_noise_strength_are_accepted(self):
FILE: acestep/api/http/release_task_param_parser.py
function _to_int (line 48) | def _to_int(value: Any, default: Optional[int] = None) -> Optional[int]:
function _to_float (line 64) | def _to_float(value: Any, default: Optional[float] = None) -> Optional[f...
function _to_bool (line 80) | def _to_bool(value: Any, default: bool = False) -> bool:
class RequestParser (line 93) | class RequestParser:
method __init__ (line 96) | def __init__(self, raw: dict):
method _parse_json (line 107) | def _parse_json(self, value: Any) -> dict:
method _find_metas (line 122) | def _find_metas(self) -> dict:
method get (line 131) | def get(self, name: str, default: Any = None):
method str (line 142) | def str(self, name: str, default: str = "") -> str:
method int (line 148) | def int(self, name: str, default: Optional[int] = None) -> Optional[int]:
method float (line 153) | def float(self, name: str, default: Optional[float] = None) -> Optiona...
method bool (line 158) | def bool(self, name: str, default: bool = False) -> bool:
FILE: acestep/api/http/release_task_param_parser_test.py
class ReleaseTaskParamParserTests (line 8) | class ReleaseTaskParamParserTests(unittest.TestCase):
method test_get_prefers_primary_raw_payload_values (line 11) | def test_get_prefers_primary_raw_payload_values(self):
method test_get_falls_back_to_param_obj_then_metas (line 23) | def test_get_falls_back_to_param_obj_then_metas(self):
method test_typed_accessors_apply_legacy_conversion_rules (line 35) | def test_typed_accessors_apply_legacy_conversion_rules(self):
method test_cover_noise_strength_and_audio_code_string_aliases_are_resolved (line 43) | def test_cover_noise_strength_and_audio_code_string_aliases_are_resolv...
method test_audio_codes_alias_resolves_to_audio_code_string (line 50) | def test_audio_codes_alias_resolves_to_audio_code_string(self):
method test_non_dict_param_obj_json_is_ignored (line 56) | def test_non_dict_param_obj_json_is_ignored(self):
FILE: acestep/api/http/release_task_request_builder.py
function build_generate_music_request (line 8) | def build_generate_music_request(
FILE: acestep/api/http/release_task_request_builder_test.py
class _FakeParser (line 9) | class _FakeParser:
method __init__ (line 12) | def __init__(self, values: dict) -> None:
method get (line 17) | def get(self, key: str):
method str (line 22) | def str(self, key: str, default: str = "") -> str:
method bool (line 28) | def bool(self, key: str, default: bool = False) -> bool:
method int (line 36) | def int(self, key: str, default=None):
method float (line 42) | def float(self, key: str, default=None):
class ReleaseTaskRequestBuilderTests (line 49) | class ReleaseTaskRequestBuilderTests(unittest.TestCase):
method test_build_request_converts_track_classes_string_to_list (line 52) | def test_build_request_converts_track_classes_string_to_list(self):
method test_build_request_prefers_explicit_audio_path_overrides (line 75) | def test_build_request_prefers_explicit_audio_path_overrides(self):
method test_build_request_allows_generic_overrides_without_kwarg_collision (line 98) | def test_build_request_allows_generic_overrides_without_kwarg_collisio...
method test_build_request_forwards_audio_code_string_and_cover_noise_strength (line 116) | def test_build_request_forwards_audio_code_string_and_cover_noise_stre...
FILE: acestep/api/http/release_task_request_parser.py
function _extract_non_file_form_values (line 15) | def _extract_non_file_form_values(form: Any) -> Dict[str, Any]:
function parse_release_task_request (line 35) | async def parse_release_task_request(
FILE: acestep/api/http/release_task_request_parser_test.py
class _FakeParser (line 14) | class _FakeParser:
method __init__ (line 17) | def __init__(self, values: dict) -> None:
method get (line 22) | def get(self, key: str):
method str (line 27) | def str(self, key: str, default: str = "") -> str:
method bool (line 33) | def bool(self, key: str, default: bool = False) -> bool:
method int (line 41) | def int(self, key: str, default=None):
method float (line 47) | def float(self, key: str, default=None):
class _FakeRequest (line 54) | class _FakeRequest:
method __init__ (line 57) | def __init__(
method json (line 74) | async def json(self):
method form (line 81) | async def form(self):
method body (line 86) | async def body(self):
class ReleaseTaskRequestParserTests (line 92) | class ReleaseTaskRequestParserTests(unittest.TestCase):
method test_json_payload_must_be_object (line 95) | def test_json_payload_must_be_object(self):
method test_missing_content_type_with_urlencoded_body_is_supported (line 121) | def test_missing_content_type_with_urlencoded_body_is_supported(self):
method test_application_json_malformed_payload_returns_400 (line 158) | def test_application_json_malformed_payload_returns_400(self):
method test_multipart_cleanup_removes_uploaded_temp_files_on_error (line 187) | def test_multipart_cleanup_removes_uploaded_temp_files_on_error(self):
FILE: acestep/api/http/release_task_route.py
function register_release_task_route (line 14) | def register_release_task_route(
FILE: acestep/api/http/release_task_route_http_test.py
class _FakeParser (line 14) | class _FakeParser:
method __init__ (line 17) | def __init__(self, values: dict) -> None:
method get (line 22) | def get(self, key: str):
method str (line 27) | def str(self, key: str, default: str = "") -> str:
method bool (line 33) | def bool(self, key: str, default: bool = False) -> bool:
method int (line 41) | def int(self, key: str, default=None):
method float (line 47) | def float(self, key: str, default=None):
class _FakeStore (line 54) | class _FakeStore:
method __init__ (line 57) | def __init__(self) -> None:
method create (line 62) | def create(self):
class ReleaseTaskRouteHttpTests (line 69) | class ReleaseTaskRouteHttpTests(unittest.TestCase):
method _build_client (line 72) | def _build_client(self, queue_maxsize: int = 8) -> TestClient:
method test_release_task_requires_auth (line 120) | def test_release_task_requires_auth(self):
method test_release_task_returns_wrapped_queue_response (line 127) | def test_release_task_returns_wrapped_queue_response(self):
method test_release_task_returns_429_when_queue_is_full (line 140) | def test_release_task_returns_429_when_queue_is_full(self):
method test_release_task_rejects_unsupported_content_type (line 151) | def test_release_task_rejects_unsupported_content_type(self):
FILE: acestep/api/http/sample_format_routes.py
function register_sample_format_routes (line 13) | def register_sample_format_routes(
FILE: acestep/api/http/sample_format_routes_http_test.py
function _wrap_response (line 13) | def _wrap_response(data, code=200, error=None):
function _verify_token_from_request (line 19) | def _verify_token_from_request(body: dict, authorization: str | None = N...
class _FakeLlm (line 29) | class _FakeLlm:
method initialize (line 34) | def initialize(self, **_kwargs):
class SampleFormatRoutesHttpTests (line 41) | class SampleFormatRoutesHttpTests(unittest.TestCase):
method _build_client (line 44) | def _build_client(self) -> TestClient:
method test_create_random_sample_requires_auth (line 81) | def test_create_random_sample_requires_auth(self):
method test_create_random_sample_returns_wrapped_payload (line 88) | def test_create_random_sample_returns_wrapped_payload(self):
method test_format_input_returns_wrapped_payload (line 101) | def test_format_input_returns_wrapped_payload(self):
FILE: acestep/api/http/sample_format_routes_test.py
function _wrap_response (line 15) | def _wrap_response(data, code=200, error=None):
function _verify_token_from_request (line 21) | def _verify_token_from_request(body: dict, authorization: str | None = N...
function _get_endpoint (line 32) | def _get_endpoint(app: FastAPI, path: str, method: str):
class _FakeLlm (line 41) | class _FakeLlm:
method __init__ (line 44) | def __init__(self) -> None:
method initialize (line 49) | def initialize(self, **_kwargs):
class SampleFormatRoutesTests (line 56) | class SampleFormatRoutesTests(unittest.TestCase):
method _build_app (line 59) | def _build_app(self) -> FastAPI:
method test_create_random_sample_returns_simple_payload (line 95) | def test_create_random_sample_returns_simple_payload(self):
method test_format_input_returns_wrapped_success_payload (line 114) | def test_format_input_returns_wrapped_success_payload(self):
method test_format_input_raises_503_when_lazy_load_disabled (line 131) | def test_format_input_raises_503_when_lazy_load_disabled(self):
FILE: acestep/api/job_analysis_runtime.py
function maybe_handle_analysis_only_modes (line 9) | def maybe_handle_analysis_only_modes(
FILE: acestep/api/job_analysis_runtime_test.py
class JobAnalysisRuntimeTests (line 13) | class JobAnalysisRuntimeTests(unittest.TestCase):
method _base_req (line 16) | def _base_req(self) -> SimpleNamespace:
method test_full_analysis_returns_expected_payload (line 27) | def test_full_analysis_returns_expected_payload(self) -> None:
method test_analysis_only_uses_lm_and_returns_payload (line 67) | def test_analysis_only_uses_lm_and_returns_payload(self) -> None:
method test_extract_codes_only_returns_expected_payload (line 98) | def test_extract_codes_only_returns_expected_payload(self) -> None:
method test_extract_codes_only_raises_when_no_src_audio (line 128) | def test_extract_codes_only_raises_when_no_src_audio(self) -> None:
method test_extract_codes_only_raises_on_extraction_failure (line 147) | def test_extract_codes_only_raises_on_extraction_failure(self) -> None:
method test_returns_none_when_no_analysis_flags (line 169) | def test_returns_none_when_no_analysis_flags(self) -> None:
FILE: acestep/api/job_blocking_generation.py
function run_blocking_generate (line 20) | def run_blocking_generate(
FILE: acestep/api/job_blocking_generation_test.py
class JobBlockingGenerationTests (line 12) | class JobBlockingGenerationTests(unittest.TestCase):
method _base_req (line 15) | def _base_req(self) -> SimpleNamespace:
method test_run_blocking_generate_success_path_updates_progress_and_builds_payload (line 18) | def test_run_blocking_generate_success_path_updates_progress_and_build...
method test_run_blocking_generate_returns_analysis_result_without_generation (line 98) | def test_run_blocking_generate_returns_analysis_result_without_generat...
FILE: acestep/api/job_execution_runtime.py
function run_one_job_runtime (line 11) | async def run_one_job_runtime(
FILE: acestep/api/job_execution_runtime_test.py
class JobExecutionRuntimeTests (line 15) | class JobExecutionRuntimeTests(unittest.IsolatedAsyncioTestCase):
method test_run_one_job_runtime_success_updates_terminal_cache (line 18) | async def test_run_one_job_runtime_success_updates_terminal_cache(self...
method test_run_one_job_runtime_failure_marks_failed_and_updates_cache (line 66) | async def test_run_one_job_runtime_failure_marks_failed_and_updates_ca...
method test_run_one_job_runtime_integration_uses_real_executor_and_wires_handler (line 114) | async def test_run_one_job_runtime_integration_uses_real_executor_and_...
FILE: acestep/api/job_generation_runtime.py
function run_generation_with_optional_sequential_cover_mode (line 8) | def run_generation_with_optional_sequential_cover_mode(
FILE: acestep/api/job_generation_runtime_test.py
class JobGenerationRuntimeTests (line 12) | class JobGenerationRuntimeTests(unittest.TestCase):
method test_runs_once_when_not_mps_cover (line 15) | def test_runs_once_when_not_mps_cover(self) -> None:
method test_splits_cover_mps_batch_into_sequential_runs (line 42) | def test_splits_cover_mps_batch_into_sequential_runs(self) -> None:
method test_raises_when_generation_fails (line 72) | def test_raises_when_generation_fails(self) -> None:
FILE: acestep/api/job_generation_setup.py
class GenerationSetup (line 17) | class GenerationSetup:
function _resolve_instruction (line 24) | def _resolve_instruction(
function _resolve_generation_seeds (line 65) | def _resolve_generation_seeds(req: Any) -> Optional[list[int]]:
function build_generation_setup (line 94) | def build_generation_setup(
FILE: acestep/api/job_generation_setup_test.py
function _base_req (line 11) | def _base_req() -> SimpleNamespace:
class JobGenerationSetupTests (line 45) | class JobGenerationSetupTests(unittest.TestCase):
method test_build_generation_setup_applies_complete_instruction_template (line 48) | def test_build_generation_setup_applies_complete_instruction_template(...
method test_build_generation_setup_applies_track_name_template (line 82) | def test_build_generation_setup_applies_track_name_template(self) -> N...
method test_build_generation_setup_resolves_seed_list_from_string (line 118) | def test_build_generation_setup_resolves_seed_list_from_string(self) -...
method test_build_generation_setup_forwards_audio_codes_and_cover_noise_strength (line 147) | def test_build_generation_setup_forwards_audio_codes_and_cover_noise_s...
FILE: acestep/api/job_llm_preparation_test.py
class JobLlmPreparationTests (line 16) | class JobLlmPreparationTests(unittest.TestCase):
method _base_req (line 19) | def _base_req(self) -> SimpleNamespace:
method test_ensure_llm_ready_for_request_respects_disabled_env (line 43) | def test_ensure_llm_ready_for_request_respects_disabled_env(self) -> N...
method test_prepare_llm_generation_inputs_updates_values_from_sample_mode (line 71) | def test_prepare_llm_generation_inputs_updates_values_from_sample_mode...
method test_prepare_llm_generation_inputs_disables_optional_cot_when_llm_unavailable (line 112) | def test_prepare_llm_generation_inputs_disables_optional_cot_when_llm_...
FILE: acestep/api/job_model_selection.py
function select_generation_handler (line 8) | def select_generation_handler(
FILE: acestep/api/job_model_selection_test.py
class JobModelSelectionTests (line 12) | class JobModelSelectionTests(unittest.TestCase):
method _app_state (line 15) | def _app_state(self) -> SimpleNamespace:
method test_select_generation_handler_defaults_to_primary (line 27) | def test_select_generation_handler_defaults_to_primary(self) -> None:
method test_select_generation_handler_uses_second_model_when_requested (line 42) | def test_select_generation_handler_uses_second_model_when_requested(se...
method test_select_generation_handler_uses_third_model_when_second_not_matched (line 59) | def test_select_generation_handler_uses_third_model_when_second_not_ma...
method test_select_generation_handler_logs_fallback_on_unknown_model (line 76) | def test_select_generation_handler_logs_fallback_on_unknown_model(self...
FILE: acestep/api/job_result_payload.py
function normalize_metas (line 8) | def normalize_metas(meta: dict[str, Any]) -> dict[str, Any]:
function _none_if_na_str (line 25) | def _none_if_na_str(value: Any) -> Optional[str]:
function _extract_seed_value (line 34) | def _extract_seed_value(audios: list[dict[str, Any]]) -> str:
function build_generation_success_response (line 44) | def build_generation_success_response(
FILE: acestep/api/job_result_payload_test.py
class JobResultPayloadTests (line 15) | class JobResultPayloadTests(unittest.TestCase):
method test_normalize_metas_maps_aliases_and_applies_defaults (line 18) | def test_normalize_metas_maps_aliases_and_applies_defaults(self) -> None:
method test_build_generation_success_response_preserves_response_contract (line 34) | def test_build_generation_success_response_preserves_response_contract...
FILE: acestep/api/job_runtime_state.py
function ensure_models_initialized (line 11) | async def ensure_models_initialized(app_state: Any) -> None:
function cleanup_job_temp_files (line 27) | async def cleanup_job_temp_files(app_state: Any, job_id: str) -> None:
function update_terminal_job_cache (line 44) | def update_terminal_job_cache(
function update_progress_job_cache (line 80) | def update_progress_job_cache(
FILE: acestep/api/job_runtime_state_test.py
class JobRuntimeStateTests (line 20) | class JobRuntimeStateTests(unittest.IsolatedAsyncioTestCase):
method test_ensure_models_initialized_raises_on_error_or_uninitialized (line 23) | async def test_ensure_models_initialized_raises_on_error_or_uninitiali...
method test_cleanup_job_temp_files_removes_tracked_paths (line 37) | async def test_cleanup_job_temp_files_removes_tracked_paths(self) -> N...
method test_cache_helpers_delegate_to_local_cache_update_functions (line 54) | async def test_cache_helpers_delegate_to_local_cache_update_functions(
FILE: acestep/api/jobs/local_cache_updates.py
function _get_record_env_and_time (line 9) | def _get_record_env_and_time(
function update_local_cache (line 22) | def update_local_cache(
function update_local_cache_progress (line 130) | def update_local_cache_progress(
FILE: acestep/api/jobs/local_cache_updates_test.py
function _map_status (line 12) | def _map_status(status: str) -> int:
class _FakeLocalCache (line 18) | class _FakeLocalCache:
method __init__ (line 21) | def __init__(self) -> None:
method set (line 26) | def set(self, key: str, value, ex: int) -> None:
class _FakeStore (line 32) | class _FakeStore:
method __init__ (line 35) | def __init__(self, records: dict[str, object] | None = None) -> None:
method get (line 40) | def get(self, job_id: str):
class LocalCacheUpdatesTests (line 46) | class LocalCacheUpdatesTests(unittest.TestCase):
method test_update_local_cache_writes_full_analysis_payload (line 49) | def test_update_local_cache_writes_full_analysis_payload(self):
method test_update_local_cache_writes_extract_codes_payload (line 73) | def test_update_local_cache_writes_extract_codes_payload(self):
method test_update_local_cache_writes_success_audio_payload (line 109) | def test_update_local_cache_writes_success_audio_payload(self):
method test_update_local_cache_writes_failed_payload (line 152) | def test_update_local_cache_writes_failed_payload(self):
method test_update_local_cache_progress_writes_running_payload (line 174) | def test_update_local_cache_progress_writes_running_payload(self):
method test_update_helpers_are_noop_without_local_cache (line 196) | def test_update_helpers_are_noop_without_local_cache(self):
FILE: acestep/api/jobs/models.py
class CreateJobResponse (line 12) | class CreateJobResponse(BaseModel):
class JobResult (line 21) | class JobResult(BaseModel):
class JobResponse (line 40) | class JobResponse(BaseModel):
FILE: acestep/api/jobs/store.py
class _JobRecord (line 19) | class _JobRecord:
function _atomic_write_json (line 38) | def _atomic_write_json(path: str, payload: Dict[str, Any]) -> None:
function _append_jsonl (line 59) | def _append_jsonl(path: str, record: Dict[str, Any]) -> None:
class _JobStore (line 68) | class _JobStore:
method __init__ (line 71) | def __init__(self, max_age_seconds: int = 86400) -> None:
method create (line 77) | def create(self) -> _JobRecord:
method create_with_id (line 93) | def create_with_id(self, job_id: str, env: str = "development") -> _Jo...
method get (line 109) | def get(self, job_id: str) -> Optional[_JobRecord]:
method mark_running (line 114) | def mark_running(self, job_id: str) -> None:
method mark_succeeded (line 124) | def mark_succeeded(self, job_id: str, result: Dict[str, Any]) -> None:
method mark_failed (line 136) | def mark_failed(self, job_id: str, error: str) -> None:
method update_progress (line 148) | def update_progress(self, job_id: str, progress: float, stage: Optiona...
method cleanup_old_jobs (line 159) | def cleanup_old_jobs(self, max_age_seconds: Optional[int] = None) -> int:
method get_stats (line 179) | def get_stats(self) -> Dict[str, int]:
method update_status_text (line 194) | def update_status_text(self, job_id: str, text: str) -> None:
method update_progress_text (line 200) | def update_progress_text(self, job_id: str, text: str) -> None:
FILE: acestep/api/jobs/store_test.py
class JobStoreTests (line 16) | class JobStoreTests(unittest.TestCase):
method test_create_mark_running_mark_succeeded_updates_state (line 19) | def test_create_mark_running_mark_succeeded_updates_state(self):
method test_cleanup_old_jobs_removes_only_completed_jobs (line 46) | def test_cleanup_old_jobs_removes_only_completed_jobs(self):
method test_update_progress_clamps_values_and_ignores_missing_jobs (line 63) | def test_update_progress_clamps_values_and_ignores_missing_jobs(self):
class JobStorePersistenceTests (line 81) | class JobStorePersistenceTests(unittest.TestCase):
method test_atomic_write_json_uses_atomic_replace_flow (line 84) | def test_atomic_write_json_uses_atomic_replace_flow(self):
method test_append_jsonl_writes_one_json_line_per_record (line 109) | def test_append_jsonl_writes_one_json_line_per_record(self):
FILE: acestep/api/jobs/test_fakes.py
class _FakeJobQueue (line 8) | class _FakeJobQueue:
method __init__ (line 11) | def __init__(self) -> None:
method task_done (line 16) | def task_done(self) -> None:
class _FakeStore (line 22) | class _FakeStore:
method __init__ (line 25) | def __init__(self, record: Optional[Any] = None) -> None:
method get (line 34) | def get(self, _job_id: str) -> Any:
method mark_failed (line 39) | def mark_failed(self, job_id: str, error: str) -> None:
method cleanup_old_jobs (line 47) | def cleanup_old_jobs(self) -> int:
method get_stats (line 57) | def get_stats(self) -> dict[str, int]:
class _DoneEvent (line 63) | class _DoneEvent:
method __init__ (line 66) | def __init__(self) -> None:
method set (line 71) | def set(self) -> None:
FILE: acestep/api/jobs/worker_loops.py
function process_queue_item (line 9) | async def process_queue_item(
function run_job_store_cleanup_loop (line 60) | async def run_job_store_cleanup_loop(
FILE: acestep/api/jobs/worker_loops_test.py
class WorkerLoopTests (line 16) | class WorkerLoopTests(unittest.TestCase):
method test_process_queue_item_success_notifies_result_and_done (line 19) | def test_process_queue_item_success_notifies_result_and_done(self):
method test_process_queue_item_failure_marks_failed_and_notifies_error (line 73) | def test_process_queue_item_failure_marks_failed_and_notifies_error(se...
method test_run_job_store_cleanup_loop_logs_cleanup_and_stops_on_cancel (line 127) | def test_run_job_store_cleanup_loop_logs_cleanup_and_stops_on_cancel(s...
method test_run_job_store_cleanup_loop_logs_errors_and_continues (line 160) | def test_run_job_store_cleanup_loop_logs_errors_and_continues(self):
FILE: acestep/api/lifespan_runtime.py
class LifespanRuntime (line 16) | class LifespanRuntime:
function _initialize_local_cache (line 30) | def _initialize_local_cache(app: Any, cache_root: str) -> None:
function initialize_lifespan_runtime (line 42) | def initialize_lifespan_runtime(
FILE: acestep/api/lifespan_runtime_test.py
class LifespanRuntimeTests (line 13) | class LifespanRuntimeTests(unittest.TestCase):
method test_initialize_lifespan_runtime_sets_expected_default_state (line 18) | def test_initialize_lifespan_runtime_sets_expected_default_state(
method test_initialize_lifespan_runtime_supports_secondary_and_third_model_handlers (line 59) | def test_initialize_lifespan_runtime_supports_secondary_and_third_mode...
FILE: acestep/api/llm_generation_inputs.py
class PreparedLlmInputs (line 10) | class PreparedLlmInputs:
function prepare_llm_generation_inputs (line 32) | def prepare_llm_generation_inputs(
FILE: acestep/api/llm_readiness.py
function ensure_llm_ready_for_request (line 9) | def ensure_llm_ready_for_request(
FILE: acestep/api/log_capture.py
class LogBuffer (line 8) | class LogBuffer:
method __init__ (line 11) | def __init__(self):
method write (line 16) | def write(self, message: str) -> None:
method flush (line 23) | def flush(self) -> None:
class StderrLogger (line 29) | class StderrLogger:
method __init__ (line 32) | def __init__(self, original_stderr: Any, buffer: LogBuffer):
method write (line 38) | def write(self, message: str) -> None:
method flush (line 44) | def flush(self) -> None:
function install_log_capture (line 50) | def install_log_capture(logger_obj: Any, stderr_obj: Any) -> tuple[LogBu...
FILE: acestep/api/log_capture_test.py
class _FakeLogger (line 11) | class _FakeLogger:
method __init__ (line 14) | def __init__(self):
method add (line 17) | def add(self, sink, format):
class LogCaptureTests (line 22) | class LogCaptureTests(unittest.TestCase):
method test_log_buffer_updates_last_message (line 25) | def test_log_buffer_updates_last_message(self) -> None:
method test_stderr_logger_forwards_to_stream_and_buffer (line 35) | def test_stderr_logger_forwards_to_stream_and_buffer(self) -> None:
method test_install_log_capture_registers_sink_and_returns_proxy (line 46) | def test_install_log_capture_registers_sink_and_returns_proxy(self) ->...
FILE: acestep/api/model_download.py
function can_access_google (line 23) | def can_access_google(timeout: float = 3.0) -> bool:
function download_from_huggingface (line 39) | def download_from_huggingface(repo_id: str, local_dir: str, model_name: ...
function download_from_modelscope (line 63) | def download_from_modelscope(repo_id: str, local_dir: str, model_name: s...
function ensure_model_downloaded (line 95) | def ensure_model_downloaded(model_name: str, checkpoint_dir: str) -> str:
FILE: acestep/api/model_download_test.py
class ModelDownloadTests (line 13) | class ModelDownloadTests(unittest.TestCase):
method test_download_from_huggingface_uses_unified_repo_target_dir (line 16) | def test_download_from_huggingface_uses_unified_repo_target_dir(self):
method test_download_from_modelscope_retries_with_cache_dir_on_type_error (line 35) | def test_download_from_modelscope_retries_with_cache_dir_on_type_error...
method test_ensure_model_downloaded_returns_existing_model_path (line 60) | def test_ensure_model_downloaded_returns_existing_model_path(self):
method test_ensure_model_downloaded_uses_huggingface_when_env_prefers_it (line 75) | def test_ensure_model_downloaded_uses_huggingface_when_env_prefers_it(...
method test_ensure_model_downloaded_falls_back_to_modelscope_from_huggingface (line 94) | def test_ensure_model_downloaded_falls_back_to_modelscope_from_hugging...
method test_ensure_model_downloaded_falls_back_to_huggingface_from_modelscope (line 113) | def test_ensure_model_downloaded_falls_back_to_huggingface_from_models...
FILE: acestep/api/route_setup.py
function configure_api_routes (line 23) | def configure_api_routes(
FILE: acestep/api/route_setup_test.py
class RouteSetupTests (line 14) | class RouteSetupTests(unittest.TestCase):
method test_configure_api_routes_registers_all_routes_and_middleware (line 26) | def test_configure_api_routes_registers_all_routes_and_middleware(
FILE: acestep/api/runtime_helpers.py
function stop_tensorboard (line 14) | def stop_tensorboard(app: Any) -> None:
function start_tensorboard (line 42) | def start_tensorboard(
function temporary_llm_model (line 80) | def temporary_llm_model(
function atomic_write_json (line 177) | def atomic_write_json(path: str, payload: Dict[str, Any]) -> None:
function append_jsonl (line 199) | def append_jsonl(path: str, record: Dict[str, Any]) -> None:
FILE: acestep/api/runtime_helpers_test.py
class RuntimeHelpersTests (line 20) | class RuntimeHelpersTests(unittest.TestCase):
method test_stop_tensorboard_terminates_and_clears_process (line 23) | def test_stop_tensorboard_terminates_and_clears_process(self):
method test_start_tensorboard_starts_process_and_returns_url (line 35) | def test_start_tensorboard_starts_process_and_returns_url(self):
method test_start_tensorboard_returns_none_on_failure (line 55) | def test_start_tensorboard_returns_none_on_failure(self):
method test_temporary_llm_model_noops_when_path_missing (line 66) | def test_temporary_llm_model_noops_when_path_missing(self):
method test_temporary_llm_model_switches_and_restores (line 85) | def test_temporary_llm_model_switches_and_restores(self):
method test_temporary_llm_model_does_not_suppress_exception_when_switch_fails (line 130) | def test_temporary_llm_model_does_not_suppress_exception_when_switch_f...
method test_atomic_write_json_replaces_target_on_success (line 163) | def test_atomic_write_json_replaces_target_on_success(self):
method test_atomic_write_json_cleans_tmp_file_on_error (line 187) | def test_atomic_write_json_cleans_tmp_file_on_error(self):
method test_append_jsonl_writes_one_line (line 212) | def test_append_jsonl_writes_one_line(self):
FILE: acestep/api/server_cli.py
function run_api_server_main (line 12) | def run_api_server_main(
FILE: acestep/api/server_cli_test.py
class ServerCliTests (line 12) | class ServerCliTests(unittest.TestCase):
method test_run_api_server_main_invokes_uvicorn_with_parsed_host_port (line 15) | def test_run_api_server_main_invokes_uvicorn_with_parsed_host_port(sel...
method test_run_api_server_main_sets_env_overrides_from_flags (line 29) | def test_run_api_server_main_sets_env_overrides_from_flags(self) -> None:
method test_run_api_server_main_uses_env_bool_for_flag_defaults (line 54) | def test_run_api_server_main_uses_env_bool_for_flag_defaults(self) -> ...
FILE: acestep/api/server_utils.py
function parse_description_hints (line 13) | def parse_description_hints(description: str) -> tuple[Optional[str], bo...
function env_bool (line 100) | def env_bool(name: str, default: bool) -> bool:
function get_model_name (line 109) | def get_model_name(config_path: str) -> str:
function map_status (line 118) | def map_status(status: str) -> int:
function parse_timesteps (line 124) | def parse_timesteps(value: Optional[str]) -> Optional[list[float]]:
function is_instrumental (line 135) | def is_instrumental(lyrics: str) -> bool:
FILE: acestep/api/server_utils_test.py
class ServerUtilsTests (line 19) | class ServerUtilsTests(unittest.TestCase):
method test_parse_description_hints_detects_language_and_instrumental (line 22) | def test_parse_description_hints_detects_language_and_instrumental(sel...
method test_parse_description_hints_empty_input (line 29) | def test_parse_description_hints_empty_input(self) -> None:
method test_parse_description_hints_detects_unicode_language_aliases (line 36) | def test_parse_description_hints_detects_unicode_language_aliases(self...
method test_env_bool_uses_truthy_values_and_default (line 43) | def test_env_bool_uses_truthy_values_and_default(self) -> None:
method test_get_model_name_normalizes_trailing_separators (line 53) | def test_get_model_name_normalizes_trailing_separators(self) -> None:
method test_map_status_returns_legacy_integer_codes (line 59) | def test_map_status_returns_legacy_integer_codes(self) -> None:
method test_parse_timesteps_parses_valid_and_rejects_invalid (line 68) | def test_parse_timesteps_parses_valid_and_rejects_invalid(self) -> None:
method test_is_instrumental_preserves_legacy_markers (line 74) | def test_is_instrumental_preserves_legacy_markers(self) -> None:
FILE: acestep/api/startup_llm_init.py
function initialize_llm_at_startup (line 11) | def initialize_llm_at_startup(
FILE: acestep/api/startup_llm_init_test.py
class StartupLlmInitTests (line 13) | class StartupLlmInitTests(unittest.TestCase):
method test_initialize_llm_at_startup_skips_when_disabled (line 16) | def test_initialize_llm_at_startup_skips_when_disabled(self) -> None:
method test_initialize_llm_at_startup_loads_recommended_model (line 48) | def test_initialize_llm_at_startup_loads_recommended_model(
FILE: acestep/api/startup_model_init.py
function initialize_models_at_startup (line 16) | def initialize_models_at_startup(
FILE: acestep/api/startup_model_init_test.py
function _gpu_config (line 13) | def _gpu_config(init_lm_default: bool = True) -> SimpleNamespace:
class StartupModelInitTests (line 28) | class StartupModelInitTests(unittest.TestCase):
method test_initialize_models_at_startup_skips_model_init_in_no_init_mode (line 34) | def test_initialize_models_at_startup_skips_model_init_in_no_init_mode(
method test_initialize_models_at_startup_initializes_primary_and_calls_llm (line 71) | def test_initialize_models_at_startup_initializes_primary_and_calls_llm(
method test_initialize_models_at_startup_raises_on_primary_init_failure (line 120) | def test_initialize_models_at_startup_raises_on_primary_init_failure(
FILE: acestep/api/train_api_dataset_auto_label_async_route.py
function register_training_dataset_auto_label_async_route (line 20) | def register_training_dataset_auto_label_async_route(
FILE: acestep/api/train_api_dataset_auto_label_routes.py
function register_training_dataset_auto_label_routes (line 21) | def register_training_dataset_auto_label_routes(
FILE: acestep/api/train_api_dataset_auto_label_routes_http_test.py
function _wrap_response (line 20) | def _wrap_response(data: Any, code: int = 200, error: Optional[str] = No...
function _verify_api_key (line 26) | async def _verify_api_key(authorization: str | None = Header(None)) -> N...
function _temporary_llm_model (line 34) | def _temporary_llm_model(_app: FastAPI, _llm: Any, _lm_model_path: Optio...
class _Sample (line 40) | class _Sample:
method __init__ (line 43) | def __init__(self, caption: str = "ready", labeled: bool = True) -> None:
method to_dict (line 60) | def to_dict(self) -> dict[str, Any]:
class _Metadata (line 80) | class _Metadata:
method to_dict (line 83) | def to_dict(self) -> dict[str, Any]:
class _Builder (line 89) | class _Builder:
method __init__ (line 92) | def __init__(self, samples: list[_Sample]) -> None:
method get_labeled_count (line 98) | def get_labeled_count(self) -> int:
method label_all_samples (line 103) | def label_all_samples(self, **_kwargs: Any) -> tuple[list[_Sample], str]:
class TrainApiDatasetAutoLabelRoutesHttpTests (line 109) | class TrainApiDatasetAutoLabelRoutesHttpTests(unittest.TestCase):
method setUp (line 112) | def setUp(self) -> None:
method tearDown (line 119) | def tearDown(self) -> None:
method _build_client (line 126) | def _build_client(self, samples: list[_Sample]) -> TestClient:
method test_auto_label_requires_auth (line 144) | def test_auto_label_requires_auth(self) -> None:
method test_auto_label_async_returns_zero_total_for_only_unlabeled_when_all_labeled (line 151) | def test_auto_label_async_returns_zero_total_for_only_unlabeled_when_a...
method test_auto_label_status_returns_wrapped_task_payload (line 167) | def test_auto_label_status_returns_wrapped_task_payload(self) -> None:
FILE: acestep/api/train_api_dataset_auto_label_status_route.py
function register_training_dataset_auto_label_status_route (line 12) | def register_training_dataset_auto_label_status_route(
FILE: acestep/api/train_api_dataset_auto_label_sync_route.py
function register_training_dataset_auto_label_sync_route (line 18) | def register_training_dataset_auto_label_sync_route(
FILE: acestep/api/train_api_dataset_models.py
class ScanDirectoryRequest (line 10) | class ScanDirectoryRequest(BaseModel):
class LoadDatasetRequest (line 20) | class LoadDatasetRequest(BaseModel):
class AutoLabelRequest (line 26) | class AutoLabelRequest(BaseModel):
method _backward_compatible_field_names (line 48) | def _backward_compatible_field_names(cls, values: Dict[str, Any]):
class SaveDatasetRequest (line 69) | class SaveDatasetRequest(BaseModel):
class UpdateSampleRequest (line 80) | class UpdateSampleRequest(BaseModel):
class PreprocessDatasetRequest (line 95) | class PreprocessDatasetRequest(BaseModel):
function _serialize_samples (line 102) | def _serialize_samples(builder: Any) -> list[Dict[str, Any]]:
FILE: acestep/api/train_api_dataset_models_test.py
class _Sample (line 12) | class _Sample:
method __init__ (line 15) | def __init__(
class _Builder (line 48) | class _Builder:
method __init__ (line 51) | def __init__(self, samples: list[_Sample]) -> None:
class TrainApiDatasetModelsTests (line 57) | class TrainApiDatasetModelsTests(unittest.TestCase):
method test_auto_label_request_maps_hunk_size_alias (line 62) | def test_auto_label_request_maps_hunk_size_alias(self) -> None:
method test_auto_label_request_maps_hunksize_alias (line 68) | def test_auto_label_request_maps_hunksize_alias(self) -> None:
method test_auto_label_request_maps_batchsize_alias (line 74) | def test_auto_label_request_maps_batchsize_alias(self) -> None:
method test_auto_label_request_keeps_explicit_values (line 80) | def test_auto_label_request_keeps_explicit_values(self) -> None:
method test_serialize_samples_returns_expected_payload_shape (line 87) | def test_serialize_samples_returns_expected_payload_shape(self) -> None:
FILE: acestep/api/train_api_dataset_preprocess_routes.py
function register_training_dataset_preprocess_routes (line 19) | def register_training_dataset_preprocess_routes(
FILE: acestep/api/train_api_dataset_preprocess_routes_http_test.py
function _wrap_response (line 16) | def _wrap_response(data: Any, code: int = 200, error: Optional[str] = No...
function _verify_api_key (line 22) | async def _verify_api_key(authorization: str | None = Header(None)) -> N...
class _Sample (line 29) | class _Sample:
method __init__ (line 32) | def __init__(self, labeled: bool) -> None:
class _Builder (line 38) | class _Builder:
method __init__ (line 41) | def __init__(self, samples: list[_Sample]) -> None:
method preprocess_to_tensors (line 46) | def preprocess_to_tensors(self, **_kwargs: Any) -> tuple[list[str], str]:
class TrainApiDatasetPreprocessRoutesHttpTests (line 52) | class TrainApiDatasetPreprocessRoutesHttpTests(unittest.TestCase):
method setUp (line 55) | def setUp(self) -> None:
method tearDown (line 62) | def tearDown(self) -> None:
method _build_client (line 69) | def _build_client(self, samples: list[_Sample]) -> TestClient:
method test_preprocess_async_returns_zero_total_when_no_labeled_samples (line 83) | def test_preprocess_async_returns_zero_total_when_no_labeled_samples(s...
method test_preprocess_status_by_task_returns_wrapped_payload (line 99) | def test_preprocess_status_by_task_returns_wrapped_payload(self) -> None:
FILE: acestep/api/train_api_dataset_sample_routes.py
function register_training_dataset_sample_routes (line 12) | def register_training_dataset_sample_routes(
FILE: acestep/api/train_api_dataset_sample_routes_http_test.py
function _wrap_response (line 16) | def _wrap_response(data: Any, code: int = 200, error: Optional[str] = No...
function _verify_api_key (line 22) | async def _verify_api_key(authorization: str | None = Header(None)) -> N...
class _Sample (line 29) | class _Sample:
method __init__ (line 32) | def __init__(self) -> None:
method to_dict (line 49) | def to_dict(self) -> dict[str, Any]:
class _Metadata (line 69) | class _Metadata:
method __init__ (line 72) | def __init__(self) -> None:
class _Builder (line 82) | class _Builder:
method __init__ (line 85) | def __init__(self) -> None:
method get_labeled_count (line 92) | def get_labeled_count(self) -> int:
method save_dataset (line 97) | def save_dataset(self, save_path: str, dataset_name: str) -> str:
method update_sample (line 103) | def update_sample(self, sample_idx: int, **_kwargs: Any) -> tuple[_Sam...
class TrainApiDatasetSampleRoutesHttpTests (line 109) | class TrainApiDatasetSampleRoutesHttpTests(unittest.TestCase):
method _build_client (line 112) | def _build_client(self) -> tuple[TestClient, _Builder]:
method test_save_dataset_updates_path_on_success (line 125) | def test_save_dataset_updates_path_on_success(self) -> None:
method test_get_sample_returns_404_when_index_out_of_range (line 142) | def test_get_sample_returns_404_when_index_out_of_range(self) -> None:
FILE: acestep/api/train_api_dataset_scan_load_routes.py
function register_training_dataset_scan_load_routes (line 13) | def register_training_dataset_scan_load_routes(
FILE: acestep/api/train_api_dataset_scan_load_routes_http_test.py
function _wrap_response (line 19) | def _wrap_response(data: Any, code: int = 200, error: Optional[str] = No...
function _verify_api_key (line 25) | async def _verify_api_key(authorization: str | None = Header(None)) -> N...
class _Sample (line 32) | class _Sample:
method __init__ (line 35) | def __init__(self, caption: str = "cap") -> None:
class _Metadata (line 53) | class _Metadata:
method __init__ (line 56) | def __init__(self) -> None:
class _ScanSuccessBuilder (line 65) | class _ScanSuccessBuilder:
method __init__ (line 68) | def __init__(self) -> None:
method scan_directory (line 76) | def scan_directory(self, _audio_dir: str) -> tuple[list[_Sample], str]:
method set_all_instrumental (line 81) | def set_all_instrumental(self, value: bool) -> None:
method set_custom_tag (line 86) | def set_custom_tag(self, tag: str, position: str) -> None:
class _LoadEmptyBuilder (line 92) | class _LoadEmptyBuilder:
method __init__ (line 95) | def __init__(self) -> None:
method load_dataset (line 101) | def load_dataset(self, _dataset_path: str) -> tuple[list[_Sample], str]:
method get_labeled_count (line 106) | def get_labeled_count(self) -> int:
class TrainApiDatasetScanLoadRoutesHttpTests (line 112) | class TrainApiDatasetScanLoadRoutesHttpTests(unittest.TestCase):
method _build_client (line 115) | def _build_client(self) -> TestClient:
method test_scan_dataset_success_sets_state_and_returns_serialized_samples (line 126) | def test_scan_dataset_success_sets_state_and_returns_serialized_sample...
method test_load_dataset_empty_returns_wrapped_400_payload (line 158) | def test_load_dataset_empty_returns_wrapped_400_payload(self) -> None:
method test_scan_dataset_requires_auth (line 177) | def test_scan_dataset_requires_auth(self) -> None:
FILE: acestep/api/train_api_dataset_service.py
function register_training_dataset_routes (line 17) | def register_training_dataset_routes(
FILE: acestep/api/train_api_dataset_service_http_test.py
function _wrap_response (line 19) | def _wrap_response(data: Any, code: int = 200, error: Optional[str] = No...
function _verify_api_key (line 25) | async def _verify_api_key(authorization: str | None = Header(None)) -> N...
function _temporary_llm_model (line 33) | def _temporary_llm_model(_app: FastAPI, _llm: Any, _lm_model_path: Optio...
class _Sample (line 39) | class _Sample:
method __init__ (line 42) | def __init__(self, caption: str = "") -> None:
method to_dict (line 59) | def to_dict(self) -> dict[str, Any]:
class _Metadata (line 79) | class _Metadata:
method __init__ (line 82) | def __init__(self) -> None:
method to_dict (line 91) | def to_dict(self) -> dict[str, Any]:
class _Builder (line 103) | class _Builder:
method __init__ (line 106) | def __init__(self) -> None:
method get_labeled_count (line 113) | def get_labeled_count(self) -> int:
method label_all_samples (line 118) | def label_all_samples(self, **kwargs: Any) -> tuple[list[Any], str]:
class _RuntimeComponentManager (line 125) | class _RuntimeComponentManager:
method __init__ (line 128) | def __init__(self, handler: Any, llm: Any, app_state: Any) -> None:
method offload_decoder_to_cpu (line 137) | def offload_decoder_to_cpu(self) -> None:
method unload_llm (line 140) | def unload_llm(self) -> None:
method restore (line 143) | def restore(self) -> None:
class TrainApiDatasetServiceHttpTests (line 147) | class TrainApiDatasetServiceHttpTests(unittest.TestCase):
method _build_client (line 150) | def _build_client(self) -> tuple[TestClient, _Builder]:
method test_auto_label_accepts_legacy_alias_fields (line 174) | def test_auto_label_accepts_legacy_alias_fields(self) -> None:
method test_get_samples_returns_wrapped_serialized_payload (line 189) | def test_get_samples_returns_wrapped_serialized_payload(self) -> None:
FILE: acestep/api/train_api_dataset_status_routes.py
function register_training_dataset_status_routes (line 12) | def register_training_dataset_status_routes(
FILE: acestep/api/train_api_dataset_status_routes_http_test.py
function _wrap_response (line 16) | def _wrap_response(data: Any, code: int = 200, error: Optional[str] = No...
function _verify_api_key (line 22) | async def _verify_api_key(authorization: str | None = Header(None)) -> N...
class TrainApiDatasetStatusRoutesHttpTests (line 29) | class TrainApiDatasetStatusRoutesHttpTests(unittest.TestCase):
method setUp (line 32) | def setUp(self) -> None:
method tearDown (line 42) | def tearDown(self) -> None:
method _build_client (line 52) | def _build_client(self) -> TestClient:
method test_preprocess_status_latest_returns_idle_when_no_task (line 63) | def test_preprocess_status_latest_returns_idle_when_no_task(self) -> N...
method test_auto_label_status_latest_returns_task_payload (line 74) | def test_auto_label_status_latest_returns_task_payload(self) -> None:
FILE: acestep/api/train_api_lokr_start_route.py
function register_lokr_training_start_route (line 20) | def register_lokr_training_start_route(
FILE: acestep/api/train_api_lora_start_route.py
function register_lora_training_start_route (line 20) | def register_lora_training_start_route(
FILE: acestep/api/train_api_models.py
class StartTrainingRequest (line 13) | class StartTrainingRequest(BaseModel):
class StartLoKRTrainingRequest (line 32) | class StartLoKRTrainingRequest(BaseModel):
class ExportLoRARequest (line 54) | class ExportLoRARequest(BaseModel):
class AutoLabelTask (line 62) | class AutoLabelTask:
class PreprocessTask (line 80) | class PreprocessTask:
function initialize_training_state (line 102) | def initialize_training_state(app: FastAPI) -> None:
FILE: acestep/api/train_api_runtime.py
function unwrap_module (line 13) | def unwrap_module(module: Any) -> Any:
class RuntimeComponentManager (line 28) | class RuntimeComponentManager:
method __init__ (line 31) | def __init__(self, handler: AceStepHandler, llm: Optional[LLMHandler],...
method _device_of (line 48) | def _device_of(module: Any) -> Optional[str]:
method _move_module (line 60) | def _move_module(module: Any, device: str, dtype: Any = None) -> None:
method move_decoder_to (line 73) | def move_decoder_to(self, device: str) -> None:
method offload_decoder_to_cpu (line 85) | def offload_decoder_to_cpu(self) -> None:
method offload_vae_to_cpu (line 98) | def offload_vae_to_cpu(self) -> None:
method offload_text_encoder_to_cpu (line 106) | def offload_text_encoder_to_cpu(self) -> None:
method offload_model_encoder_to_cpu (line 114) | def offload_model_encoder_to_cpu(self) -> None:
method unload_llm (line 123) | def unload_llm(self) -> None:
method restore (line 136) | def restore(self) -> None:
FILE: acestep/api/train_api_service.py
function register_training_api_routes (line 19) | def register_training_api_routes(
FILE: acestep/api/train_api_service_http_test.py
function _wrap_response (line 16) | def _wrap_response(data: Any, code: int = 200, error: Optional[str] = No...
function _verify_api_key (line 22) | async def _verify_api_key(authorization: str | None = Header(None)) -> N...
function _temporary_llm_model (line 30) | def _temporary_llm_model(_app: FastAPI, _llm: Any, _lm_model_path: Optio...
class TrainingApiServiceHttpTests (line 36) | class TrainingApiServiceHttpTests(unittest.TestCase):
method _build_client (line 39) | def _build_client(self) -> tuple[TestClient, dict[str, int], FastAPI]:
method test_training_status_requires_auth (line 67) | def test_training_status_requires_auth(self):
method test_training_status_returns_wrapped_payload (line 74) | def test_training_status_returns_wrapped_payload(self):
method test_training_stop_sets_should_stop_and_calls_tensorboard_stop (line 86) | def test_training_stop_sets_should_stop_and_calls_tensorboard_stop(self):
method test_training_stop_returns_idle_message_when_not_training (line 103) | def test_training_stop_returns_idle_message_when_not_training(self):
method test_load_tensor_info_returns_400_for_missing_dir (line 118) | def test_load_tensor_info_returns_400_for_missing_dir(self):
FILE: acestep/api/worker_runtime.py
function _queue_worker_loop (line 12) | async def _queue_worker_loop(
function _job_store_cleanup_worker_loop (line 33) | async def _job_store_cleanup_worker_loop(*, store: Any, cleanup_interval...
function start_worker_tasks (line 42) | def start_worker_tasks(
function stop_worker_tasks (line 76) | def stop_worker_tasks(
FILE: acestep/api/worker_runtime_test.py
class WorkerRuntimeTests (line 14) | class WorkerRuntimeTests(unittest.IsolatedAsyncioTestCase):
method test_start_and_stop_worker_tasks_processes_queue_items (line 19) | async def test_start_and_stop_worker_tasks_processes_queue_items(
FILE: acestep/api_server.py
function _get_project_root (line 100) | def _get_project_root() -> str:
function _wrap_response (line 120) | def _wrap_response(data: Any, code: int = 200, error: Optional[str] = No...
function _load_all_examples (line 139) | def _load_all_examples(sample_mode: str = "simple_mode") -> List[Dict[st...
function _load_project_env (line 164) | def _load_project_env() -> None:
function create_app (line 187) | def create_app() -> FastAPI:
function main (line 359) | def main() -> None:
FILE: acestep/audio_utils.py
function apply_fade (line 24) | def apply_fade(
function normalize_audio (line 71) | def normalize_audio(audio_data: Union[torch.Tensor, np.ndarray], target_...
class AudioSaver (line 113) | class AudioSaver:
method __init__ (line 116) | def __init__(self, default_format: str = "flac"):
method save_audio (line 128) | def save_audio(
method convert_audio (line 260) | def convert_audio(
method save_batch (line 304) | def save_batch(
function get_lora_weights_hash (line 354) | def get_lora_weights_hash(dit_handler) -> str:
function get_audio_file_hash (line 414) | def get_audio_file_hash(audio_file) -> str:
function generate_uuid_from_params (line 440) | def generate_uuid_from_params(params_dict) -> str:
function generate_uuid_from_audio_data (line 459) | def generate_uuid_from_audio_data(
function save_audio (line 493) | def save_audio(
FILE: acestep/audio_utils_test.py
class AudioSaverFormatTests (line 14) | class AudioSaverFormatTests(unittest.TestCase):
method setUp (line 17) | def setUp(self):
method tearDown (line 23) | def tearDown(self):
method test_init_accepts_opus_format (line 28) | def test_init_accepts_opus_format(self):
method test_init_accepts_aac_format (line 33) | def test_init_accepts_aac_format(self):
method test_init_accepts_all_formats (line 38) | def test_init_accepts_all_formats(self):
method test_init_rejects_invalid_format (line 44) | def test_init_rejects_invalid_format(self):
method test_save_audio_validates_opus_format (line 49) | def test_save_audio_validates_opus_format(self):
method test_save_audio_validates_aac_format (line 69) | def test_save_audio_validates_aac_format(self):
method test_save_audio_opus_uses_ffmpeg_backend (line 89) | def test_save_audio_opus_uses_ffmpeg_backend(self):
method test_save_audio_aac_uses_ffmpeg_backend (line 106) | def test_save_audio_aac_uses_ffmpeg_backend(self):
method test_extension_handling_for_opus (line 123) | def test_extension_handling_for_opus(self):
method test_extension_handling_for_aac (line 139) | def test_extension_handling_for_aac(self):
method test_m4a_extension_accepted_for_aac (line 155) | def test_m4a_extension_accepted_for_aac(self):
method test_save_audio_invalid_format_fallback (line 170) | def test_save_audio_invalid_format_fallback(self):
method test_numpy_array_input_with_opus (line 186) | def test_numpy_array_input_with_opus(self):
method test_convenience_function_supports_opus (line 204) | def test_convenience_function_supports_opus(self):
method test_convenience_function_supports_aac (line 218) | def test_convenience_function_supports_aac(self):
class ApplyFadeTests (line 233) | class ApplyFadeTests(unittest.TestCase):
method setUp (line 236) | def setUp(self):
method test_no_fade_returns_unchanged_tensor (line 247) | def test_no_fade_returns_unchanged_tensor(self):
method test_no_fade_returns_unchanged_numpy (line 252) | def test_no_fade_returns_unchanged_numpy(self):
method test_fade_in_first_sample_is_zero (line 257) | def test_fade_in_first_sample_is_zero(self):
method test_fade_in_last_ramp_sample_near_one (line 262) | def test_fade_in_last_ramp_sample_near_one(self):
method test_fade_out_last_sample_is_zero (line 269) | def test_fade_out_last_sample_is_zero(self):
method test_fade_out_first_ramp_sample_near_one (line 274) | def test_fade_out_first_ramp_sample_near_one(self):
method test_both_fades_combined (line 281) | def test_both_fades_combined(self):
method test_fade_preserves_type_tensor (line 290) | def test_fade_preserves_type_tensor(self):
method test_fade_preserves_type_numpy (line 295) | def test_fade_preserves_type_numpy(self):
method test_fade_does_not_modify_input_tensor (line 300) | def test_fade_does_not_modify_input_tensor(self):
method test_fade_does_not_modify_input_numpy (line 306) | def test_fade_does_not_modify_input_numpy(self):
method test_fade_clamps_to_signal_length (line 316) | def test_fade_clamps_to_signal_length(self):
method test_fade_in_numpy_first_sample_is_zero (line 324) | def test_fade_in_numpy_first_sample_is_zero(self):
method test_fade_out_numpy_last_sample_is_zero (line 329) | def test_fade_out_numpy_last_sample_is_zero(self):
FILE: acestep/audio_utils_uuid_test.py
class _FakeLoraService (line 13) | class _FakeLoraService:
method __init__ (line 16) | def __init__(self, registry=None):
class _FakeHandler (line 20) | class _FakeHandler:
method __init__ (line 23) | def __init__(self, lora_loaded=False, use_lora=False, registry=None):
class UuidGenerationTest (line 29) | class UuidGenerationTest(unittest.TestCase):
method test_different_lora_states_produce_different_uuids (line 32) | def test_different_lora_states_produce_different_uuids(self):
method test_different_lora_scale_produces_different_uuids (line 62) | def test_different_lora_scale_produces_different_uuids(self):
method test_same_params_produce_same_uuid (line 86) | def test_same_params_produce_same_uuid(self):
method test_uuid_format_is_valid (line 102) | def test_uuid_format_is_valid(self):
method test_lora_weights_hash_empty_when_no_lora (line 126) | def test_lora_weights_hash_empty_when_no_lora(self):
method test_lora_weights_hash_empty_when_use_lora_false (line 131) | def test_lora_weights_hash_empty_when_use_lora_false(self):
method test_different_lora_files_produce_different_hashes (line 136) | def test_different_lora_files_produce_different_hashes(self):
method test_same_lora_file_produces_same_hash (line 172) | def test_same_lora_file_produces_same_hash(self):
method test_lora_weights_hash_differentiates_uuids (line 192) | def test_lora_weights_hash_differentiates_uuids(self):
class AudioCodesPreservationTest (line 206) | class AudioCodesPreservationTest(unittest.TestCase):
method _build_audio_params (line 215) | def _build_audio_params(base_params, lm_codes_list, idx):
method test_user_codes_preserved_when_lm_returns_empty (line 224) | def test_user_codes_preserved_when_lm_returns_empty(self):
method test_lm_codes_overwrite_when_non_empty (line 232) | def test_lm_codes_overwrite_when_non_empty(self):
method test_user_codes_preserved_when_lm_list_empty (line 239) | def test_user_codes_preserved_when_lm_list_empty(self):
FILE: acestep/cli_args.py
function parse_quantization_arg (line 15) | def parse_quantization_arg(value: str | None) -> str | None:
FILE: acestep/cli_args_test.py
class ParseQuantizationArgTests (line 11) | class ParseQuantizationArgTests(unittest.TestCase):
method test_returns_none_for_none_aliases (line 14) | def test_returns_none_for_none_aliases(self) -> None:
method test_returns_canonical_quantization_values (line 21) | def test_returns_canonical_quantization_values(self) -> None:
method test_raises_for_invalid_value (line 30) | def test_raises_for_invalid_value(self) -> None:
FILE: acestep/constrained_logits_processor.py
class FSMState (line 53) | class FSMState(Enum):
class MetadataConstrainedLogitsProcessor (line 81) | class MetadataConstrainedLogitsProcessor(LogitsProcessor):
method __init__ (line 102) | def __init__(
method _get_next_field_state (line 262) | def _get_next_field_state(self, current_field: str) -> Optional[FSMSta...
method _build_state_transitions (line 309) | def _build_state_transitions(self):
method set_skip_genres (line 352) | def set_skip_genres(self, skip: bool):
method set_skip_caption (line 357) | def set_skip_caption(self, skip: bool):
method set_skip_language (line 362) | def set_skip_language(self, skip: bool):
method postprocess_caption (line 368) | def postprocess_caption(caption: str) -> str:
method set_stop_at_reasoning (line 400) | def set_stop_at_reasoning(self, stop: bool):
method set_generation_phase (line 410) | def set_generation_phase(self, phase: str):
method set_user_metadata (line 425) | def set_user_metadata(self, metadata: Optional[Dict[str, Optional[str]...
method _precompute_tokens (line 461) | def _precompute_tokens(self):
method _precompute_audio_code_tokens (line 548) | def _precompute_audio_code_tokens(self):
method _extract_code_from_token (line 585) | def _extract_code_from_token(self, token_id: int) -> Optional[int]:
method _build_audio_code_mask (line 608) | def _build_audio_code_mask(self):
method _apply_whitelist_inplace (line 649) | def _apply_whitelist_inplace(self, scores: torch.Tensor, allowed_token...
method _build_keyscale_prefix_tree (line 676) | def _build_keyscale_prefix_tree(self) -> Dict[Tuple[int, ...], Set[int]]:
method _build_numeric_prefix_tree (line 788) | def _build_numeric_prefix_tree(
method _build_language_prefix_tree (line 851) | def _build_language_prefix_tree(self) -> Dict[Tuple[int, ...], Set[int]]:
method diagnose_keyscale_prefix_tree (line 913) | def diagnose_keyscale_prefix_tree(self):
method _load_genres_vocab (line 953) | def _load_genres_vocab(self):
method _build_genres_trie (line 984) | def _build_genres_trie(self):
method _extract_caption_genres (line 1004) | def _extract_caption_genres(self, caption: str):
method _collect_complete_genres (line 1060) | def _collect_complete_genres(self, node: Dict, prefix: str, result: se...
method _precompute_char_token_mapping (line 1079) | def _precompute_char_token_mapping(self):
method _try_reload_genres_vocab (line 1131) | def _try_reload_genres_vocab(self):
method _get_genres_trie_node (line 1143) | def _get_genres_trie_node(self, prefix: str) -> Optional[Dict]:
method _is_complete_genre (line 1155) | def _is_complete_genre(self, text: str) -> bool:
method _get_trie_node_from_trie (line 1160) | def _get_trie_node_from_trie(self, trie: Dict, prefix: str) -> Optiona...
method _get_allowed_genres_tokens (line 1169) | def _get_allowed_genres_tokens(self) -> List[int]:
method reset (line 1271) | def reset(self):
method set_target_duration (line 1285) | def set_target_duration(self, duration: Optional[float]):
method set_max_duration (line 1303) | def set_max_duration(self, max_duration: int):
method _get_allowed_tokens_for_fixed_string (line 1335) | def _get_allowed_tokens_for_fixed_string(self, fixed_str: str) -> List...
method _get_allowed_digit_tokens (line 1407) | def _get_allowed_digit_tokens(self, min_val: int, max_val: int) -> Lis...
method _get_allowed_numeric_tokens (line 1444) | def _get_allowed_numeric_tokens(self, prefix_tree: Dict[Tuple[int, ......
method _should_end_numeric_field (line 1465) | def _should_end_numeric_field(self, logits: torch.Tensor, min_val: int...
method _should_end_text_field (line 1495) | def _should_end_text_field(self, logits: torch.Tensor) -> bool:
method _get_allowed_keyscale_tokens (line 1514) | def _get_allowed_keyscale_tokens(self) -> List[int]:
method _is_keyscale_complete (line 1529) | def _is_keyscale_complete(self) -> bool:
method _get_allowed_language_tokens (line 1540) | def _get_allowed_language_tokens(self) -> List[int]:
method _get_allowed_timesig_tokens (line 1554) | def _get_allowed_timesig_tokens(self) -> List[int]:
method __call__ (line 1568) | def __call__(
method _input_contains_think_end_tag (line 1641) | def _input_contains_think_end_tag(self, input_ids: torch.LongTensor) -...
method _apply_temperature_scaling (line 1666) | def _apply_temperature_scaling(self, scores: torch.FloatTensor) -> tor...
method _get_user_provided_field_tokens (line 1697) | def _get_user_provided_field_tokens(self, field_name: str) -> Optional...
method _process_single_sequence (line 1743) | def _process_single_sequence(
method _transition_to_next_state (line 2109) | def _transition_to_next_state(self):
method update_state (line 2139) | def update_state(self, generated_token_id: int):
FILE: acestep/core/generation/handler/audio_codes.py
class AudioCodesMixin (line 11) | class AudioCodesMixin:
method _parse_audio_code_string (line 20) | def _parse_audio_code_string(self, code_str: str) -> List[int]:
method _decode_audio_codes_to_latents (line 47) | def _decode_audio_codes_to_latents(self, code_str: str) -> Optional[to...
method convert_src_audio_to_codes (line 68) | def convert_src_audio_to_codes(self, audio_file) -> str:
FILE: acestep/core/generation/handler/batch_prep.py
class BatchPrepMixin (line 10) | class BatchPrepMixin:
method _normalize_audio_code_hints (line 19) | def _normalize_audio_code_hints(
method _normalize_instructions (line 37) | def _normalize_instructions(
method _create_fallback_vocal_languages (line 59) | def _create_fallback_vocal_languages(self, batch_size: int) -> List[str]:
method _encode_audio_to_latents (line 63) | def _encode_audio_to_latents(self, audio: torch.Tensor) -> torch.Tensor:
method prepare_batch_data (line 78) | def prepare_batch_data(
FILE: acestep/core/generation/handler/conditioning_batch.py
class ConditioningBatchMixin (line 10) | class ConditioningBatchMixin:
method _prepare_batch (line 21) | def _prepare_batch(
FILE: acestep/core/generation/handler/conditioning_batch_test.py
class _Host (line 11) | class _Host(ConditioningBatchMixin):
method __init__ (line 14) | def __init__(self):
method _normalize_audio_code_hints (line 19) | def _normalize_audio_code_hints(self, audio_code_hints, batch_size: in...
method _create_fallback_vocal_languages (line 24) | def _create_fallback_vocal_languages(self, batch_size: int) -> List[str]:
method _get_vae_dtype (line 27) | def _get_vae_dtype(self) -> torch.dtype:
method _parse_metas (line 30) | def _parse_metas(self, metas) -> List[str]:
method _normalize_instructions (line 35) | def _normalize_instructions(self, instructions, batch_size: int, defau...
method _prepare_target_latents_and_wavs (line 40) | def _prepare_target_latents_and_wavs(
method _build_chunk_masks_and_src_latents (line 48) | def _build_chunk_masks_and_src_latents(
method _prepare_precomputed_lm_hints (line 67) | def _prepare_precomputed_lm_hints(
method _prepare_text_conditioning_inputs (line 78) | def _prepare_text_conditioning_inputs(
class ConditioningBatchMixinTests (line 100) | class ConditioningBatchMixinTests(unittest.TestCase):
method test_prepare_batch_builds_expected_keys_and_tensor_types (line 103) | def test_prepare_batch_builds_expected_keys_and_tensor_types(self):
method test_prepare_batch_populates_non_cover_inputs_when_strength_below_one (line 128) | def test_prepare_batch_populates_non_cover_inputs_when_strength_below_...
FILE: acestep/core/generation/handler/conditioning_embed.py
class ConditioningEmbedMixin (line 9) | class ConditioningEmbedMixin:
method infer_refer_latent (line 18) | def infer_refer_latent(self, refer_audioss: List[List[torch.Tensor]]) ...
method infer_text_embeddings (line 71) | def infer_text_embeddings(self, text_token_idss):
method infer_lyric_embeddings (line 76) | def infer_lyric_embeddings(self, lyric_token_ids):
method preprocess_batch (line 81) | def preprocess_batch(self, batch) -> Tuple:
FILE: acestep/core/generation/handler/conditioning_embed_test.py
class _FakeTextEncoder (line 11) | class _FakeTextEncoder:
method __call__ (line 14) | def __call__(self, input_ids, lyric_attention_mask=None):
method embed_tokens (line 19) | def embed_tokens(self, token_ids):
class _Host (line 24) | class _Host(ConditioningEmbedMixin):
method __init__ (line 27) | def __init__(self):
method _ensure_silence_latent_on_device (line 34) | def _ensure_silence_latent_on_device(self):
method _load_model_context (line 38) | def _load_model_context(self, _name):
method tiled_encode (line 41) | def tiled_encode(self, audio, offload_latent_to_cpu=True):
class ConditioningEmbedMixinTests (line 48) | class ConditioningEmbedMixinTests(unittest.TestCase):
method test_infer_refer_latent_returns_latents_and_order_mask (line 51) | def test_infer_refer_latent_returns_latents_and_order_mask(self):
method test_infer_refer_latent_cache_hit_reuses_encoding (line 63) | def test_infer_refer_latent_cache_hit_reuses_encoding(self):
method test_infer_refer_latent_uses_silence_fast_path (line 72) | def test_infer_refer_latent_uses_silence_fast_path(self):
method test_infer_refer_latent_handles_multiple_references_per_item (line 80) | def test_infer_refer_latent_handles_multiple_references_per_item(self):
method test_preprocess_batch_returns_expected_tuple_shape (line 88) | def test_preprocess_batch_returns_expected_tuple_shape(self):
FILE: acestep/core/generation/handler/conditioning_masks.py
class ConditioningMaskMixin (line 12) | class ConditioningMaskMixin:
method _build_chunk_masks_and_src_latents (line 19) | def _build_chunk_masks_and_src_latents(
FILE: acestep/core/generation/handler/conditioning_masks_test.py
class _Host (line 14) | class _Host(ConditioningMaskMixin):
method __init__ (line 17) | def __init__(self):
function _make_host (line 22) | def _make_host():
function _build (line 26) | def _build(
class ConditioningMaskLegoBehaviorTests (line 61) | class ConditioningMaskLegoBehaviorTests(unittest.TestCase):
method test_lego_with_repainting_range_preserves_source_latents (line 69) | def test_lego_with_repainting_range_preserves_source_latents(self):
method test_lego_default_instruction_preserves_source_latents (line 92) | def test_lego_default_instruction_preserves_source_latents(self):
method test_repaint_full_range_silences_repainting_region (line 109) | def test_repaint_full_range_silences_repainting_region(self):
method test_repaint_partial_range_silences_only_masked_region (line 132) | def test_repaint_partial_range_silences_only_masked_region(self):
method test_lego_instruction_marker_constant (line 159) | def test_lego_instruction_marker_constant(self):
method test_lego_detection_is_case_insensitive (line 173) | def test_lego_detection_is_case_insensitive(self):
method test_lego_with_empty_instructions_does_not_raise (line 191) | def test_lego_with_empty_instructions_does_not_raise(self):
method test_non_lego_instruction_still_silences_repaint (line 207) | def test_non_lego_instruction_still_silences_repaint(self):
method test_no_source_audio_produces_silence_latents (line 225) | def test_no_source_audio_produces_silence_latents(self):
FILE: acestep/core/generation/handler/conditioning_target.py
class ConditioningTargetMixin (line 9) | class ConditioningTargetMixin:
method _get_silence_latent_slice (line 18) | def _get_silence_latent_slice(self, length: int) -> torch.Tensor:
method _prepare_target_latents_and_wavs (line 35) | def _prepare_target_latents_and_wavs(
FILE: acestep/core/generation/handler/conditioning_text.py
class ConditioningTextMixin (line 11) | class ConditioningTextMixin:
method _prepare_precomputed_lm_hints (line 20) | def _prepare_precomputed_lm_hints(
method _prepare_text_conditioning_inputs (line 57) | def _prepare_text_conditioning_inputs(
FILE: acestep/core/generation/handler/cover_noise_strength_forwarding_test.py
class CoverNoiseStrengthForwardingTests (line 17) | class CoverNoiseStrengthForwardingTests(unittest.TestCase):
method test_service_generate_forwards_cover_noise_strength (line 20) | def test_service_generate_forwards_cover_noise_strength(self) -> None:
FILE: acestep/core/generation/handler/diffusion.py
class DiffusionMixin (line 9) | class DiffusionMixin:
method _mlx_run_diffusion (line 18) | def _mlx_run_diffusion(
FILE: acestep/core/generation/handler/diffusion_test.py
class _Host (line 10) | class _Host(DiffusionMixin):
method __init__ (line 11) | def __init__(self, device: str = "cpu", dtype: torch.dtype = torch.flo...
class _IterableTimesteps (line 17) | class _IterableTimesteps:
method __init__ (line 18) | def __init__(self, values):
method __iter__ (line 21) | def __iter__(self):
class DiffusionMixinTests (line 25) | class DiffusionMixinTests(unittest.TestCase):
method test_mlx_run_diffusion_converts_inputs_and_outputs_tensor (line 26) | def test_mlx_run_diffusion_converts_inputs_and_outputs_tensor(self):
method test_mlx_run_diffusion_handles_optional_and_iterable_timesteps (line 74) | def test_mlx_run_diffusion_handles_optional_and_iterable_timesteps(self):
method test_mlx_run_diffusion_rejects_invalid_infer_method (line 101) | def test_mlx_run_diffusion_rejects_invalid_infer_method(self):
method test_mlx_run_diffusion_rejects_non_iterable_timesteps (line 114) | def test_mlx_run_diffusion_rejects_non_iterable_timesteps(self):
method test_mlx_run_diffusion_rejects_batch_mismatch (line 127) | def test_mlx_run_diffusion_rejects_batch_mismatch(self):
method test_mlx_run_diffusion_requires_host_attributes (line 138) | def test_mlx_run_diffusion_requires_host_attributes(self):
FILE: acestep/core/generation/handler/generate_music.py
function _resolve_repaint_config (line 25) | def _resolve_repaint_config(
class GenerateMusicMixin (line 50) | class GenerateMusicMixin:
method _vram_preflight_check (line 57) | def _vram_preflight_check(
method generate_music (line 123) | def generate_music(
FILE: acestep/core/generation/handler/generate_music_decode.py
class GenerateMusicDecodeMixin (line 14) | class GenerateMusicDecodeMixin:
method _prepare_generate_music_decode_state (line 17) | def _prepare_generate_music_decode_state(
method _decode_generate_music_pred_latents (line 99) | def _decode_generate_music_pred_latents(
FILE: acestep/core/generation/handler/generate_music_decode_test.py
function _load_generate_music_decode_module (line 14) | def _load_generate_music_decode_module():
class _FakeDecodeOutput (line 49) | class _FakeDecodeOutput:
method __init__ (line 52) | def __init__(self, sample: torch.Tensor):
class _FakeVae (line 57) | class _FakeVae:
method __init__ (line 60) | def __init__(self):
method decode (line 65) | def decode(self, latents: torch.Tensor):
method parameters (line 69) | def parameters(self):
method cpu (line 73) | def cpu(self):
method to (line 77) | def to(self, *_args, **_kwargs):
class _Host (line 82) | class _Host(GenerateMusicDecodeMixin):
method __init__ (line 85) | def __init__(self):
method _update_progress_estimate (line 97) | def _update_progress_estimate(self, **kwargs):
method _load_model_context (line 102) | def _load_model_context(self, _model_name):
method _empty_cache (line 106) | def _empty_cache(self):
method _memory_allocated (line 110) | def _memory_allocated(self):
method _max_memory_allocated (line 114) | def _max_memory_allocated(self):
method _mlx_vae_decode (line 118) | def _mlx_vae_decode(self, latents):
method tiled_decode (line 123) | def tiled_decode(self, latents):
class GenerateMusicDecodeMixinTests (line 129) | class GenerateMusicDecodeMixinTests(unittest.TestCase):
method test_prepare_decode_state_updates_progress_estimates (line 132) | def test_prepare_decode_state_updates_progress_estimates(self):
method test_prepare_decode_state_raises_for_nan_latents (line 152) | def test_prepare_decode_state_raises_for_nan_latents(self):
method test_decode_pred_latents_updates_decode_time_and_returns_cpu_latents (line 169) | def test_decode_pred_latents_updates_decode_time_and_returns_cpu_laten...
method test_decode_pred_latents_restores_vae_device_on_decode_error (line 194) | def test_decode_pred_latents_restores_vae_device_on_decode_error(self):
method test_decode_pred_latents_does_not_restore_latents_to_gpu_after_successful_cpu_decode (line 254) | def test_decode_pred_latents_does_not_restore_latents_to_gpu_after_suc...
FILE: acestep/core/generation/handler/generate_music_execute.py
class GenerateMusicExecuteMixin (line 15) | class GenerateMusicExecuteMixin:
method _run_generate_music_service_with_progress (line 18) | def _run_generate_music_service_with_progress(
FILE: acestep/core/generation/handler/generate_music_execute_test.py
class _Host (line 8) | class _Host(GenerateMusicExecuteMixin):
method __init__ (line 11) | def __init__(self):
method _start_diffusion_progress_estimator (line 17) | def _start_diffusion_progress_estimator(self, **kwargs):
method service_generate (line 42) | def service_generate(self, **kwargs):
class GenerateMusicExecuteMixinTests (line 49) | class GenerateMusicExecuteMixinTests(unittest.TestCase):
method test_run_service_with_progress_invokes_service_and_stops_estimator (line 52) | def test_run_service_with_progress_invokes_service_and_stops_estimator...
FILE: acestep/core/generation/handler/generate_music_payload.py
class GenerateMusicPayloadMixin (line 8) | class GenerateMusicPayloadMixin:
method _build_generate_music_success_payload (line 11) | def _build_generate_music_success_payload(
FILE: acestep/core/generation/handler/generate_music_payload_test.py
function _load_generate_music_payload_module (line 17) | def _load_generate_music_payload_module():
class _Host (line 58) | class _Host(GenerateMusicPayloadMixin):
method __init__ (line 61) | def __init__(self):
class GenerateMusicPayloadMixinTests (line 66) | class GenerateMusicPayloadMixinTests(unittest.TestCase):
method test_build_success_payload_contains_audio_and_extra_outputs (line 69) | def test_build_success_payload_contains_audio_and_extra_outputs(self):
method test_build_success_payload_handles_missing_optional_outputs_without_progress (line 110) | def test_build_success_payload_handles_missing_optional_outputs_withou...
method test_build_success_payload_does_not_mutate_outputs_dict (line 138) | def test_build_success_payload_does_not_mutate_outputs_dict(self):
method test_build_success_payload_all_extra_outputs_are_cpu_tensors (line 166) | def test_build_success_payload_all_extra_outputs_are_cpu_tensors(self):
FILE: acestep/core/generation/handler/generate_music_request.py
class GenerateMusicRequestMixin (line 11) | class GenerateMusicRequestMixin:
method _resolve_generate_music_progress (line 14) | def _resolve_generate_music_progress(
method _validate_generate_music_readiness (line 29) | def _validate_generate_music_readiness(self) -> Optional[Dict[str, Any]]:
method _has_non_empty_audio_codes (line 41) | def _has_non_empty_audio_codes(self, value: Union[str, List[str]]) -> ...
method _resolve_generate_music_task (line 47) | def _resolve_generate_music_task(
method _prepare_generate_music_runtime (line 58) | def _prepare_generate_music_runtime(
method _prepare_reference_and_source_audio (line 86) | def _prepare_reference_and_source_audio(
method _prepare_generate_music_service_inputs (line 138) | def _prepare_generate_music_service_inputs(
FILE: acestep/core/generation/handler/generate_music_request_test.py
class _Host (line 11) | class _Host(GenerateMusicRequestMixin):
method __init__ (line 14) | def __init__(self):
class GenerateMusicRequestMixinTests (line 34) | class GenerateMusicRequestMixinTests(unittest.TestCase):
method test_resolve_task_switches_to_cover_when_audio_codes_present (line 37) | def test_resolve_task_switches_to_cover_when_audio_codes_present(self):
method test_prepare_runtime_normalizes_batch_and_duration (line 48) | def test_prepare_runtime_normalizes_batch_and_duration(self):
method test_prepare_reference_and_source_audio_returns_error_for_invalid_reference (line 62) | def test_prepare_reference_and_source_audio_returns_error_for_invalid_...
method test_prepare_reference_and_source_audio_ignores_src_audio_for_text2music (line 77) | def test_prepare_reference_and_source_audio_ignores_src_audio_for_text...
method test_prepare_reference_and_source_audio_returns_error_for_invalid_source (line 98) | def test_prepare_reference_and_source_audio_returns_error_for_invalid_...
method test_should_return_intermediate_always_true (line 115) | def test_should_return_intermediate_always_true(self):
FILE: acestep/core/generation/handler/generate_music_test.py
function _load_generate_music_module (line 19) | def _load_generate_music_module():
class _Host (line 60) | class _Host(GenerateMusicMixin):
method __init__ (line 67) | def __init__(self, offload_to_cpu: bool = False):
method _resolve_generate_music_progress (line 85) | def _resolve_generate_music_progress(self, progress):
method _validate_generate_music_readiness (line 97) | def _validate_generate_music_readiness(self):
method _resolve_generate_music_task (line 102) | def _resolve_generate_music_task(self, **kwargs):
method _prepare_generate_music_runtime (line 107) | def _prepare_generate_music_runtime(self, **kwargs):
method _prepare_reference_and_source_audio (line 118) | def _prepare_reference_and_source_audio(self, **kwargs):
method _prepare_generate_music_service_inputs (line 123) | def _prepare_generate_music_service_inputs(self, **kwargs):
method _run_generate_music_service_with_progress (line 128) | def _run_generate_music_service_with_progress(self, **kwargs):
method _prepare_generate_music_decode_state (line 139) | def _prepare_generate_music_decode_state(self, **kwargs):
method _decode_generate_music_pred_latents (line 144) | def _decode_generate_music_pred_latents(self, **kwargs):
method _build_generate_music_success_payload (line 149) | def _build_generate_music_success_payload(self, **kwargs):
method _empty_cache (line 154) | def _empty_cache(self):
class GenerateMusicMixinTests (line 158) | class GenerateMusicMixinTests(unittest.TestCase):
method test_generate_music_returns_success_payload_from_builder (line 161) | def test_generate_music_returns_success_payload_from_builder(self):
method test_generate_music_returns_readiness_error_when_components_missing (line 178) | def test_generate_music_returns_readiness_error_when_components_missin...
method test_generate_music_returns_error_payload_on_exception (line 187) | def test_generate_music_returns_error_payload_on_exception(self):
class VramPreflightCheckTests (line 202) | class VramPreflightCheckTests(unittest.TestCase):
method test_preflight_skips_when_offload_to_cpu_enabled (line 208) | def test_preflight_skips_when_offload_to_cpu_enabled(self, mock_torch):
method test_preflight_blocks_when_offload_disabled_and_vram_low (line 221) | def test_preflight_blocks_when_offload_disabled_and_vram_low(
method test_preflight_passes_when_offload_disabled_and_vram_sufficient (line 238) | def test_preflight_passes_when_offload_disabled_and_vram_sufficient(
method test_preflight_passes_on_non_cuda_device (line 252) | def test_preflight_passes_on_non_cuda_device(self, mock_torch):
FILE: acestep/core/generation/handler/init_service.py
class InitServiceMixin (line 13) | class InitServiceMixin(
FILE: acestep/core/generation/handler/init_service_catalog.py
class InitServiceCatalogMixin (line 10) | class InitServiceCatalogMixin:
method _device_type (line 13) | def _device_type(self) -> str:
method get_available_checkpoints (line 19) | def get_available_checkpoints(self) -> List[str]:
method get_available_acestep_v15_models (line 27) | def get_available_acestep_v15_models(self) -> List[str]:
method is_flash_attention_available (line 42) | def is_flash_attention_available(self, device: Optional[str] = None) -...
method is_turbo_model (line 69) | def is_turbo_model(self) -> bool:
FILE: acestep/core/generation/handler/init_service_downloads.py
class InitServiceDownloadsMixin (line 16) | class InitServiceDownloadsMixin:
method _ensure_models_present (line 19) | def _ensure_models_present(
method _sync_model_code_if_needed (line 49) | def _sync_model_code_if_needed(config_path: str, checkpoint_path: Path...
FILE: acestep/core/generation/handler/init_service_loader.py
class InitServiceLoaderMixin (line 13) | class InitServiceLoaderMixin(InitServiceLoaderComponentsMixin):
method _cuda_supports_bool_argsort (line 16) | def _cuda_supports_bool_argsort(self) -> bool:
method _apply_cuda_bool_argsort_workaround (line 34) | def _apply_cuda_bool_argsort_workaround(self) -> None:
method _build_quantization_config (line 78) | def _build_quantization_config(quantization: str):
method _apply_dit_quantization (line 91) | def _apply_dit_quantization(self, quantization: Optional[str]) -> None:
method _load_main_model_from_checkpoint (line 114) | def _load_main_model_from_checkpoint(
FILE: acestep/core/generation/handler/init_service_loader_components.py
class InitServiceLoaderComponentsMixin (line 8) | class InitServiceLoaderComponentsMixin:
method _load_vae_model (line 18) | def _load_vae_model(self, *, checkpoint_dir: str, device: str, compile...
method _load_text_encoder_and_tokenizer (line 59) | def _load_text_encoder_and_tokenizer(self, *, checkpoint_dir: str, dev...
FILE: acestep/core/generation/handler/init_service_memory_basic.py
class InitServiceMemoryBasicMixin (line 7) | class InitServiceMemoryBasicMixin:
method _empty_cache (line 10) | def _empty_cache(self):
method _synchronize (line 20) | def _synchronize(self):
method _memory_allocated (line 30) | def _memory_allocated(self):
method _max_memory_allocated (line 37) | def _max_memory_allocated(self):
method _is_on_target_device (line 44) | def _is_on_target_device(self, tensor, target_device):
method _get_affine_quantized_tensor_class (line 64) | def _get_affine_quantized_tensor_class():
method _is_quantized_tensor (line 84) | def _is_quantized_tensor(self, t):
method _has_quantized_params (line 93) | def _has_quantized_params(self, module):
method _ensure_silence_latent_on_device (line 103) | def _ensure_silence_latent_on_device(self):
FILE: acestep/core/generation/handler/init_service_memory_transfer.py
class InitServiceMemoryTransferMixin (line 7) | class InitServiceMemoryTransferMixin:
method _move_module_recursive (line 10) | def _move_module_recursive(self, module, target_device, dtype=None, vi...
method _move_quantized_param (line 59) | def _move_quantized_param(self, param, target_device):
method _recursive_to_device (line 69) | def _recursive_to_device(self, model, device, dtype=None):
FILE: acestep/core/generation/handler/init_service_offload_context.py
class InitServiceOffloadContextMixin (line 10) | class InitServiceOffloadContextMixin:
method _load_model_context (line 14) | def _load_model_context(self, model_name: str):
FILE: acestep/core/generation/handler/init_service_orchestrator.py
function _cuda_supports_bfloat16 (line 20) | def _cuda_supports_bfloat16() -> bool:
function _resolve_rocm_dtype (line 25) | def _resolve_rocm_dtype() -> torch.dtype:
class InitServiceOrchestratorMixin (line 45) | class InitServiceOrchestratorMixin:
method initialize_service (line 48) | def initialize_service(
FILE: acestep/core/generation/handler/init_service_setup.py
class InitServiceSetupMixin (line 11) | class InitServiceSetupMixin:
method _resolve_initialize_device (line 14) | def _resolve_initialize_device(self, requested_device: str) -> str:
method _configure_initialize_runtime (line 58) | def _configure_initialize_runtime(
method _ensure_len_for_compile (line 85) | def _ensure_len_for_compile(model: Any, method_name: str) -> None:
method _validate_quantization_setup (line 102) | def _validate_quantization_setup(self, *, quantization: Optional[str],...
method _initialize_mlx_backends (line 114) | def _initialize_mlx_backends(
method _build_initialize_status_message (line 149) | def _build_initialize_status_message(
FILE: acestep/core/generation/handler/init_service_test.py
function _load_init_service_module (line 17) | def _load_init_service_module():
class _Host (line 52) | class _Host(InitServiceMixin):
method __init__ (line 55) | def __init__(self, project_root: str, device: str = "cpu", config=None):
method _get_project_root (line 76) | def _get_project_root(self):
method _get_vae_dtype (line 80) | def _get_vae_dtype(self, _device: str = "cpu"):
method _init_mlx_dit (line 84) | def _init_mlx_dit(self, compile_model: bool = False) -> bool:
method _init_mlx_vae (line 89) | def _init_mlx_vae(self) -> bool:
class InitServiceMixinTests (line 94) | class InitServiceMixinTests(unittest.TestCase):
method test_device_type_normalizes_device (line 97) | def test_device_type_normalizes_device(self):
method test_is_on_target_device_handles_device_alias (line 102) | def test_is_on_target_device_handles_device_alias(self):
method test_is_on_target_device_fallback_does_not_assume_cuda (line 109) | def test_is_on_target_device_fallback_does_not_assume_cuda(self):
method test_is_on_target_device_malformed_target_logs_and_returns_false (line 115) | def test_is_on_target_device_malformed_target_logs_and_returns_false(s...
method test_get_auto_decode_chunk_size_uses_cuda_device_index (line 124) | def test_get_auto_decode_chunk_size_uses_cuda_device_index(self):
method test_vram_guard_reduce_batch_uses_cuda_device_index (line 142) | def test_vram_guard_reduce_batch_uses_cuda_device_index(self):
method test_move_module_recursive_preserves_parameter_type (line 167) | def test_move_module_recursive_preserves_parameter_type(self):
method test_move_quantized_param_fallback_wraps_parameter (line 176) | def test_move_quantized_param_fallback_wraps_parameter(self):
method test_get_available_checkpoints_returns_expected_list (line 184) | def test_get_available_checkpoints_returns_expected_list(self):
method test_get_available_acestep_v15_models_filters_and_sorts (line 193) | def test_get_available_acestep_v15_models_filters_and_sorts(self):
method test_is_turbo_model_uses_config_flag (line 210) | def test_is_turbo_model_uses_config_flag(self):
method test_is_flash_attention_available_rejects_non_cuda (line 218) | def test_is_flash_attention_available_rejects_non_cuda(self):
method test_is_flash_attention_available_true_when_cuda_and_module_present (line 224) | def test_is_flash_attention_available_true_when_cuda_and_module_presen...
method test_is_flash_attention_available_false_when_pre_ampere_gpu (line 232) | def test_is_flash_attention_available_false_when_pre_ampere_gpu(self):
method test_is_flash_attention_available_false_when_module_missing (line 240) | def test_is_flash_attention_available_false_when_module_missing(self):
method test_resolve_initialize_device_auto_prefers_cuda (line 256) | def test_resolve_initialize_device_auto_prefers_cuda(self):
method test_configure_initialize_runtime_redirects_compile_on_mps (line 264) | def test_configure_initialize_runtime_redirects_compile_on_mps(self):
method test_configure_initialize_runtime_keeps_settings_on_cuda (line 276) | def test_configure_initialize_runtime_keeps_settings_on_cuda(self):
method test_resolve_initialize_device_requested_cuda_falls_back_to_cpu (line 288) | def test_resolve_initialize_device_requested_cuda_falls_back_to_cpu(se...
method test_resolve_initialize_device_requested_cuda_falls_back_to_mps (line 296) | def test_resolve_initialize_device_requested_cuda_falls_back_to_mps(se...
method test_validate_quantization_setup_allows_quantization_without_compile_model (line 304) | def test_validate_quantization_setup_allows_quantization_without_compi...
method test_ensure_models_present_returns_download_error_when_main_model_fails (line 318) | def test_ensure_models_present_returns_download_error_when_main_model_...
method test_build_initialize_status_message_reports_mlx_compile_label (line 330) | def test_build_initialize_status_message_reports_mlx_compile_label(self):
method test_initialize_mlx_backends_disables_dit_when_requested (line 350) | def test_initialize_mlx_backends_disables_dit_when_requested(self):
method test_initialize_service_returns_model_precheck_failure (line 365) | def test_initialize_service_returns_model_precheck_failure(self):
method test_initialize_service_clears_stale_state_on_model_precheck_failure (line 377) | def test_initialize_service_clears_stale_state_on_model_precheck_failu...
method test_initialize_service_uses_provided_project_root_for_checkpoints (line 403) | def test_initialize_service_uses_provided_project_root_for_checkpoints...
method test_initialize_service_success_uses_decomposed_helpers (line 433) | def test_initialize_service_success_uses_decomposed_helpers(self):
method test_initialize_service_returns_error_payload_when_loader_raises (line 481) | def test_initialize_service_returns_error_payload_when_loader_raises(s...
method test_load_main_model_ignores_cuda_sync_cleanup_error (line 498) | def test_load_main_model_ignores_cuda_sync_cleanup_error(self):
method test_apply_cuda_bool_argsort_workaround_patches_pack_sequences (line 538) | def test_apply_cuda_bool_argsort_workaround_patches_pack_sequences(self):
method test_cuda_supports_bool_argsort_returns_false_for_unexpected_runtime_error (line 561) | def test_cuda_supports_bool_argsort_returns_false_for_unexpected_runti...
method test_apply_dit_quantization_filters_to_decoder_linear_layers (line 576) | def test_apply_dit_quantization_filters_to_decoder_linear_layers(self):
method test_validate_quantization_setup_raises_import_error_when_torchao_missing (line 614) | def test_validate_quantization_setup_raises_import_error_when_torchao_...
method test_initialize_service_disables_quantization_when_torchao_is_incompatible (line 633) | def test_initialize_service_disables_quantization_when_torchao_is_inco...
method test_get_affine_quantized_tensor_class_returns_none_on_torchao_attr_error (line 658) | def test_get_affine_quantized_tensor_class_returns_none_on_torchao_att...
method test_load_model_context_yields_immediately_when_offload_disabled (line 676) | def test_load_model_context_yields_immediately_when_offload_disabled(s...
method test_load_model_context_loads_and_offloads_when_enabled_for_vae (line 686) | def test_load_model_context_loads_and_offloads_when_enabled_for_vae(se...
method test_recursive_to_device_uses_quantized_move_fallback (line 698) | def test_recursive_to_device_uses_quantized_move_fallback(self):
method test_empty_cache_routes_to_cuda (line 718) | def test_empty_cache_routes_to_cuda(self):
method test_empty_cache_routes_to_xpu (line 725) | def test_empty_cache_routes_to_xpu(self):
method test_empty_cache_routes_to_mps (line 734) | def test_empty_cache_routes_to_mps(self):
method test_synchronize_routes_to_cuda (line 741) | def test_synchronize_routes_to_cuda(self):
method test_synchronize_routes_to_xpu (line 748) | def test_synchronize_routes_to_xpu(self):
method test_synchronize_routes_to_mps (line 757) | def test_synchronize_routes_to_mps(self):
method test_memory_queries_use_cuda_only (line 764) | def test_memory_queries_use_cuda_only(self):
class _VaeHost (line 788) | class _VaeHost(_Host):
class RocmDtypeTests (line 798) | class RocmDtypeTests(unittest.TestCase):
method _make_rocm_host (line 801) | def _make_rocm_host(self, device: str = "cuda") -> _Host:
method test_resolve_rocm_dtype_defaults_to_float32 (line 807) | def test_resolve_rocm_dtype_defaults_to_float32(self):
method test_resolve_rocm_dtype_respects_float16_override (line 814) | def test_resolve_rocm_dtype_respects_float16_override(self):
method test_resolve_rocm_dtype_respects_bfloat16_override (line 820) | def test_resolve_rocm_dtype_respects_bfloat16_override(self):
method test_resolve_rocm_dtype_unknown_value_falls_back_to_float32 (line 826) | def test_resolve_rocm_dtype_unknown_value_falls_back_to_float32(self):
method test_initialize_service_uses_float32_on_rocm (line 832) | def test_initialize_service_uses_float32_on_rocm(self):
method test_initialize_service_uses_bfloat16_on_non_rocm_cuda (line 870) | def test_initialize_service_uses_bfloat16_on_non_rocm_cuda(self):
method test_initialize_service_uses_float16_on_pre_ampere_cuda (line 907) | def test_initialize_service_uses_float16_on_pre_ampere_cuda(self):
method test_get_vae_dtype_returns_self_dtype_on_rocm (line 944) | def test_get_vae_dtype_returns_self_dtype_on_rocm(self):
method test_get_vae_dtype_rocm_override_propagates_float16 (line 952) | def test_get_vae_dtype_rocm_override_propagates_float16(self):
method test_get_vae_dtype_returns_bfloat16_on_non_rocm_cuda (line 960) | def test_get_vae_dtype_returns_bfloat16_on_non_rocm_cuda(self):
method test_get_vae_dtype_returns_float16_on_pre_ampere_cuda (line 969) | def test_get_vae_dtype_returns_float16_on_pre_ampere_cuda(self):
method test_get_vae_dtype_treats_cuda_index_device_as_cuda (line 978) | def test_get_vae_dtype_treats_cuda_index_device_as_cuda(self):
method test_load_text_encoder_uses_cpu_safe_dtype_when_offloaded (line 988) | def test_load_text_encoder_uses_cpu_safe_dtype_when_offloaded(self):
FILE: acestep/core/generation/handler/io_audio.py
class IoAudioMixin (line 13) | class IoAudioMixin:
method _normalize_audio_to_stereo_48k (line 20) | def _normalize_audio_to_stereo_48k(
method process_target_audio (line 44) | def process_target_audio(self, audio_file: Optional[str]) -> Optional[...
method process_reference_audio (line 69) | def process_reference_audio(
method process_src_audio (line 134) | def process_src_audio(self, audio_file: Optional[str]) -> Optional[tor...
FILE: acestep/core/generation/handler/io_audio_test.py
class _Host (line 14) | class _Host(IoAudioMixin):
method is_silence (line 17) | def is_silence(self, audio: torch.Tensor) -> bool:
function _fake_torchaudio_module (line 22) | def _fake_torchaudio_module(load_fn):
class IoAudioMixinTests (line 30) | class IoAudioMixinTests(unittest.TestCase):
method test_normalize_audio_to_stereo_48k_duplicates_mono_and_clamps (line 33) | def test_normalize_audio_to_stereo_48k_duplicates_mono_and_clamps(self):
method test_process_target_audio_loads_and_normalizes (line 43) | def test_process_target_audio_loads_and_normalizes(self):
method test_process_src_audio_handles_load_error (line 57) | def test_process_src_audio_handles_load_error(self):
method test_process_reference_audio_returns_none_for_silence (line 65) | def test_process_reference_audio_returns_none_for_silence(self):
method test_process_reference_audio_samples_expected_segments (line 74) | def test_process_reference_audio_samples_expected_segments(self):
method test_process_reference_audio_returns_none_on_load_error (line 97) | def test_process_reference_audio_returns_none_on_load_error(self):
FILE: acestep/core/generation/handler/lora/adapter_discovery.py
function collect_adapter_names (line 4) | def collect_adapter_names(self) -> list[str]:
FILE: acestep/core/generation/handler/lora/controls.py
function _toggle_lokr (line 12) | def _toggle_lokr(decoder, enable: bool, scale: float = 1.0) -> bool:
function set_use_lora (line 35) | def set_use_lora(self, use_lora: bool) -> str:
function set_lora_scale (line 83) | def set_lora_scale(self, adapter_name_or_scale: str | float, scale: floa...
function set_active_lora_adapter (line 193) | def set_active_lora_adapter(self, adapter_name: str) -> str:
function get_lora_status (line 208) | def get_lora_status(self) -> dict[str, Any]:
FILE: acestep/core/generation/handler/lora/controls_test.py
class _DummyHandler (line 14) | class _DummyHandler:
method __init__ (line 17) | def __init__(self, adapter_type=None) -> None:
method _ensure_lora_registry (line 33) | def _ensure_lora_registry(self):
method _rebuild_lora_registry (line 36) | def _rebuild_lora_registry(self, lora_path=None):
method _sync_lora_state_from_service (line 39) | def _sync_lora_state_from_service(self):
method _apply_scale_to_adapter (line 42) | def _apply_scale_to_adapter(self, name, scale):
method set_lora_scale (line 45) | def set_lora_scale(self, adapter_name_or_scale, scale=None):
class ToggleLokrTests (line 49) | class ToggleLokrTests(unittest.TestCase):
method test_disable_sets_multiplier_to_zero (line 52) | def test_disable_sets_multiplier_to_zero(self):
method test_enable_sets_multiplier_to_scale (line 60) | def test_enable_sets_multiplier_to_scale(self):
method test_returns_false_when_no_lycoris_net (line 68) | def test_returns_false_when_no_lycoris_net(self):
method test_returns_false_when_no_set_multiplier (line 74) | def test_returns_false_when_no_set_multiplier(self):
class SetUseLokrTests (line 81) | class SetUseLokrTests(unittest.TestCase):
method test_disable_lokr_zeros_multiplier (line 84) | def test_disable_lokr_zeros_multiplier(self):
method test_enable_lokr_restores_multiplier (line 97) | def test_enable_lokr_restores_multiplier(self):
method test_enable_lokr_uses_lora_scale_fallback (line 112) | def test_enable_lokr_uses_lora_scale_fallback(self):
class SetUsePeftLoraTests (line 126) | class SetUsePeftLoraTests(unittest.TestCase):
method test_disable_peft_lora_calls_disable_adapter_layers (line 129) | def test_disable_peft_lora_calls_disable_adapter_layers(self):
method test_enable_peft_lora_calls_enable_adapter_layers (line 141) | def test_enable_peft_lora_calls_enable_adapter_layers(self):
method test_no_adapter_loaded_returns_error (line 156) | def test_no_adapter_loaded_returns_error(self):
class SetLokrScaleTests (line 166) | class SetLokrScaleTests(unittest.TestCase):
method test_scale_lokr_sets_multiplier (line 169) | def test_scale_lokr_sets_multiplier(self):
method test_scale_lokr_when_disabled_stores_but_does_not_apply (line 182) | def test_scale_lokr_when_disabled_stores_but_does_not_apply(self):
FILE: acestep/core/generation/handler/lora/lifecycle.py
function _is_lokr_safetensors (line 17) | def _is_lokr_safetensors(weights_path: str) -> bool:
function _resolve_lokr_weights_path (line 39) | def _resolve_lokr_weights_path(adapter_path: str) -> str | None:
function _validate_peft_adapter_config (line 61) | def _validate_peft_adapter_config(config_file: str) -> str | None:
function _load_lokr_config (line 87) | def _load_lokr_config(weights_path: str) -> LoKRConfig:
function _load_lokr_adapter (line 128) | def _load_lokr_adapter(decoder: Any, weights_path: str) -> Any:
function _default_adapter_name_from_path (line 185) | def _default_adapter_name_from_path(lora_path: str) -> str:
function add_lora (line 191) | def add_lora(self, lora_path: str, adapter_name: str | None = None) -> str:
function load_lora (line 319) | def load_lora(self, lora_path: str) -> str:
function add_voice_lora (line 328) | def add_voice_lora(self, lora_path: str, scale: float = 1.0) -> str:
function remove_lora (line 336) | def remove_lora(self, adapter_name: str) -> str:
function unload_lora (line 437) | def unload_lora(self) -> str:
FILE: acestep/core/generation/handler/lora/lifecycle_test.py
class _DummyDecoder (line 14) | class _DummyDecoder:
method __init__ (line 17) | def __init__(self) -> None:
method state_dict (line 20) | def state_dict(self):
method load_state_dict (line 24) | def load_state_dict(self, state_dict, strict=False):
method to (line 29) | def to(self, *_args, **_kwargs):
method eval (line 33) | def eval(self):
class _DummyHandler (line 38) | class _DummyHandler:
method __init__ (line 41) | def __init__(self) -> None:
method _ensure_lora_registry (line 58) | def _ensure_lora_registry(self):
method _rebuild_lora_registry (line 62) | def _rebuild_lora_registry(self, lora_path=None):
method _debug_lora_registry_snapshot (line 67) | def _debug_lora_registry_snapshot(self):
method add_lora (line 71) | def add_lora(self, lora_path, adapter_name=None):
class LifecycleTests (line 76) | class LifecycleTests(unittest.TestCase):
method test_resolve_lokr_weights_from_directory (line 79) | def test_resolve_lokr_weights_from_directory(self):
method test_resolve_lokr_weights_from_file (line 87) | def test_resolve_lokr_weights_from_file(self):
method test_resolve_lokr_weights_from_custom_safetensors_name (line 95) | def test_resolve_lokr_weights_from_custom_safetensors_name(self):
method test_load_lora_accepts_lokr_directory_without_adapter_config (line 110) | def test_load_lora_accepts_lokr_directory_without_adapter_config(self):
method test_load_lora_invalid_adapter_message_mentions_lokr (line 124) | def test_load_lora_invalid_adapter_message_mentions_lokr(self):
method test_validate_peft_adapter_config_missing_peft_type (line 132) | def test_validate_peft_adapter_config_missing_peft_type(self):
method test_validate_peft_adapter_config_valid (line 142) | def test_validate_peft_adapter_config_valid(self):
method test_validate_peft_adapter_config_invalid_json (line 150) | def test_validate_peft_adapter_config_invalid_json(self):
method test_validate_peft_adapter_config_not_a_dict (line 159) | def test_validate_peft_adapter_config_not_a_dict(self):
method test_add_lora_returns_clear_error_when_peft_type_missing (line 167) | def test_add_lora_returns_clear_error_when_peft_type_missing(self):
method test_load_lokr_adapter_recreates_with_dora_when_weight_decompose_enabled (line 177) | def test_load_lokr_adapter_recreates_with_dora_when_weight_decompose_e...
method test_load_lokr_adapter_uses_base_net_when_dora_not_supported (line 201) | def test_load_lokr_adapter_uses_base_net_when_dora_not_supported(self):
method test_unload_lora_restores_lokr_adapter_before_state_restore (line 224) | def test_unload_lora_restores_lokr_adapter_before_state_restore(self):
method test_unload_lora_fails_when_lokr_restore_raises (line 247) | def test_unload_lora_fails_when_lokr_restore_raises(self):
FILE: acestep/core/generation/handler/lora/registry_builder.py
function rebuild_lora_registry (line 9) | def rebuild_lora_registry(self, lora_path: str | None = None) -> tuple[i...
FILE: acestep/core/generation/handler/lora/registry_state.py
function _decoder_from_host (line 8) | def _decoder_from_host(self):
function _copy_registry (line 13) | def _copy_registry(registry: dict[str, dict[str, Any]]) -> dict[str, dic...
function sync_lora_state_from_service (line 30) | def sync_lora_state_from_service(self) -> None:
function ensure_lora_registry (line 38) | def ensure_lora_registry(self) -> None:
function debug_lora_registry_snapshot (line 59) | def debug_lora_registry_snapshot(self, max_targets_per_adapter: int = 20...
FILE: acestep/core/generation/handler/lora/scale_apply.py
function apply_scale_to_adapter (line 9) | def apply_scale_to_adapter(self, adapter_name: str, scale: float) -> int:
FILE: acestep/core/generation/handler/lora_integration_test.py
class FakeDecoder (line 6) | class FakeDecoder:
method __init__ (line 7) | def __init__(self, modules, adapter_names):
method named_modules (line 11) | def named_modules(self):
method get_adapter_names (line 14) | def get_adapter_names(self):
class FakeModel (line 18) | class FakeModel:
method __init__ (line 19) | def __init__(self, decoder):
class FakeSetScaleModule (line 23) | class FakeSetScaleModule:
method __init__ (line 24) | def __init__(self):
method set_scale (line 29) | def set_scale(self, adapter_name, factor):
class MinimalHandler (line 33) | class MinimalHandler(LoraManagerMixin):
method __init__ (line 34) | def __init__(self, decoder):
class LoraHandlerIntegrationTests (line 45) | class LoraHandlerIntegrationTests(unittest.TestCase):
method test_handler_state_snapshot_does_not_mutate_service (line 46) | def test_handler_state_snapshot_does_not_mutate_service(self):
method test_set_lora_scale_reports_skipped_targets (line 60) | def test_set_lora_scale_reports_skipped_targets(self):
method test_set_lora_scale_reports_no_modules_found (line 70) | def test_set_lora_scale_reports_no_modules_found(self):
method test_get_lora_status_exposes_synthetic_default_mode (line 79) | def test_get_lora_status_exposes_synthetic_default_mode(self):
method test_set_lora_scale_rejects_non_numeric_input (line 89) | def test_set_lora_scale_rejects_non_numeric_input(self):
method test_set_use_lora_handles_missing_model_decoder (line 97) | def test_set_use_lora_handles_missing_model_decoder(self):
FILE: acestep/core/generation/handler/lora_manager.py
class LoraManagerMixin (line 11) | class LoraManagerMixin:
FILE: acestep/core/generation/handler/lyric_alignment_common.py
class LyricAlignmentCommonMixin (line 8) | class LyricAlignmentCommonMixin:
method _resolve_custom_layers_config (line 11) | def _resolve_custom_layers_config(
method _move_alignment_inputs_to_runtime (line 19) | def _move_alignment_inputs_to_runtime(
method _sample_noise_like (line 36) | def _sample_noise_like(self, reference: torch.Tensor, seed: Optional[i...
method _extract_lyric_segment (line 50) | def _extract_lyric_segment(
method _lyric_timestamp_error (line 73) | def _lyric_timestamp_error(self, message: str) -> Dict[str, Any]:
method _lyric_score_error (line 83) | def _lyric_score_error(self, message: str) -> Dict[str, Any]:
FILE: acestep/core/generation/handler/lyric_alignment_test.py
class _Tokenizer (line 14) | class _Tokenizer:
method encode (line 17) | def encode(self, _text, add_special_tokens=False):
class _Decoder (line 23) | class _Decoder:
method __init__ (line 26) | def __init__(self, cross_attns):
method eval (line 30) | def eval(self):
method __call__ (line 33) | def __call__(self, **kwargs):
class _Model (line 39) | class _Model:
method __init__ (line 42) | def __init__(self, decoder):
class _Host (line 47) | class _Host(LyricTimestampMixin, LyricScoreMixin):
method __init__ (line 50) | def __init__(self, decoder):
method _load_model_context (line 58) | def _load_model_context(self, _name):
class LyricAlignmentMixinTests (line 63) | class LyricAlignmentMixinTests(unittest.TestCase):
method _sample_inputs (line 66) | def _sample_inputs(self):
method test_get_lyric_timestamp_success (line 75) | def test_get_lyric_timestamp_success(self):
method test_get_lyric_score_success (line 117) | def test_get_lyric_score_success(self):
method test_get_lyric_timestamp_returns_error_when_attentions_missing (line 159) | def test_get_lyric_timestamp_returns_error_when_attentions_missing(self):
method test_get_lyric_score_returns_error_when_attentions_missing (line 177) | def test_get_lyric_score_returns_error_when_attentions_missing(self):
FILE: acestep/core/generation/handler/lyric_score.py
class LyricScoreMixin (line 11) | class LyricScoreMixin(LyricAlignmentCommonMixin):
method get_lyric_score (line 15) | def get_lyric_score(
method _calculate_single_lyric_score (line 168) | def _calculate_single_lyric_score(
FILE: acestep/core/generation/handler/lyric_timestamp.py
class LyricTimestampMixin (line 11) | class LyricTimestampMixin(LyricAlignmentCommonMixin):
method get_lyric_timestamp (line 15) | def get_lyric_timestamp(
FILE: acestep/core/generation/handler/memory_utils.py
function _is_cuda_device (line 17) | def _is_cuda_device(device: object) -> bool:
function _cuda_device_index (line 26) | def _cuda_device_index(device: object) -> int:
class MemoryUtilsMixin (line 44) | class MemoryUtilsMixin:
method is_silence (line 51) | def is_silence(self, audio: torch.Tensor) -> bool:
method _get_system_memory_gb (line 55) | def _get_system_memory_gb(self) -> Optional[float]:
method _get_effective_mps_memory_gb (line 66) | def _get_effective_mps_memory_gb(self) -> Optional[float]:
method _get_auto_decode_chunk_size (line 80) | def _get_auto_decode_chunk_size(self) -> int:
method _should_offload_wav_to_cpu (line 117) | def _should_offload_wav_to_cpu(self) -> bool:
method _vram_guard_reduce_batch (line 137) | def _vram_guard_reduce_batch(
method _get_vae_dtype (line 191) | def _get_vae_dtype(self, device: Optional[str] = None) -> torch.dtype:
FILE: acestep/core/generation/handler/metadata_utils.py
class MetadataMixin (line 6) | class MetadataMixin:
method _create_default_meta (line 13) | def _create_default_meta(self) -> str:
method _dict_to_meta_string (line 22) | def _dict_to_meta_string(self, meta_dict: Dict[str, Any]) -> str:
method _parse_metas (line 41) | def _parse_metas(self, metas: List[Union[str, Dict[str, Any]]]) -> Lis...
method prepare_metadata (line 56) | def prepare_metadata(
method _build_metadata_dict (line 62) | def _build_metadata_dict(
FILE: acestep/core/generation/handler/mlx_dit_init.py
class MlxDitInitMixin (line 6) | class MlxDitInitMixin:
method _init_mlx_dit (line 9) | def _init_mlx_dit(self, compile_model: bool = False) -> bool:
FILE: acestep/core/generation/handler/mlx_dit_init_test.py
function _load_handler_module (line 11) | def _load_handler_module(filename: str, module_name: str):
class _DitHost (line 43) | class _DitHost(MlxDitInitMixin):
method __init__ (line 46) | def __init__(self):
class MlxDitInitMixinTests (line 55) | class MlxDitInitMixinTests(unittest.TestCase):
method test_init_mlx_dit_unavailable_returns_false (line 58) | def test_init_mlx_dit_unavailable_returns_false(self):
method test_init_mlx_dit_success_sets_decoder (line 68) | def test_init_mlx_dit_success_sets_decoder(self):
FILE: acestep/core/generation/handler/mlx_vae_decode_native.py
class MlxVaeDecodeNativeMixin (line 12) | class MlxVaeDecodeNativeMixin:
method _resolve_mlx_decode_fn (line 15) | def _resolve_mlx_decode_fn(self):
method _mlx_vae_decode (line 31) | def _mlx_vae_decode(self, latents_torch):
method _mlx_decode_single (line 74) | def _mlx_decode_single(self, z_nlc, decode_fn=None):
FILE: acestep/core/generation/handler/mlx_vae_encode_native.py
class MlxVaeEncodeNativeMixin (line 12) | class MlxVaeEncodeNativeMixin:
method _resolve_mlx_encode_fn (line 15) | def _resolve_mlx_encode_fn(self):
method _mlx_vae_encode_sample (line 31) | def _mlx_vae_encode_sample(self, audio_torch):
method _mlx_encode_single (line 89) | def _mlx_encode_single(self, audio_nlc, pbar=None, encode_fn=None):
FILE: acestep/core/generation/handler/mlx_vae_init.py
class MlxVaeInitMixin (line 9) | class MlxVaeInitMixin:
method _init_mlx_vae (line 12) | def _init_mlx_vae(self) -> bool:
FILE: acestep/core/generation/handler/mlx_vae_init_test.py
function _load_handler_module (line 9) | def _load_handler_module(filename: str, module_name: str) -> types.Modul...
class _VaeHost (line 55) | class _VaeHost(MlxVaeInitMixin):
method __init__ (line 58) | def __init__(self):
class _FakeMlxVae (line 64) | class _FakeMlxVae:
method decode (line 67) | def decode(self, value):
method encode_and_sample (line 71) | def encode_and_sample(self, value):
method from_pytorch_config (line 76) | def from_pytorch_config(cls, _vae):
method update (line 80) | def update(self, _params):
method parameters (line 84) | def parameters(self):
function _build_fake_mx_core (line 87) | def _build_fake_mx_core(raise_compile: bool) -> tuple[types.ModuleType, ...
class MlxVaeInitMixinTests (line 118) | class MlxVaeInitMixinTests(unittest.TestCase):
method test_init_mlx_vae_unavailable_returns_false (line 121) | def test_init_mlx_vae_unavailable_returns_false(self):
method test_init_mlx_vae_success_sets_compiled_callables (line 131) | def test_init_mlx_vae_success_sets_compiled_callables(self):
method test_init_mlx_vae_compile_failure_falls_back (line 162) | def test_init_mlx_vae_compile_failure_falls_back(self):
FILE: acestep/core/generation/handler/mlx_vae_native_test.py
function _load_handler_module (line 11) | def _load_handler_module(module_filename: str, module_name: str):
class _Progress (line 46) | class _Progress:
method __init__ (line 49) | def __init__(self, *_args, **_kwargs):
method update (line 53) | def update(self, amount):
method close (line 57) | def close(self):
class _Host (line 62) | class _Host(MlxVaeDecodeNativeMixin, MlxVaeEncodeNativeMixin):
method __init__ (line 65) | def __init__(self):
function _fake_mx_core_module (line 77) | def _fake_mx_core_module():
class MlxVaeNativeMixinTests (line 89) | class MlxVaeNativeMixinTests(unittest.TestCase):
method test_mlx_decode_single_without_tiling_uses_decode_fn (line 92) | def test_mlx_decode_single_without_tiling_uses_decode_fn(self):
method test_mlx_decode_single_with_tiling_concatenates_trimmed_chunks (line 106) | def test_mlx_decode_single_with_tiling_concatenates_trimmed_chunks(self):
method test_mlx_vae_decode_returns_torch_tensor_with_expected_shape (line 120) | def test_mlx_vae_decode_returns_torch_tensor_with_expected_shape(self):
method test_mlx_encode_single_without_tiling_updates_progress (line 132) | def test_mlx_encode_single_without_tiling_updates_progress(self):
method test_mlx_encode_single_with_tiling_updates_progress_per_chunk (line 145) | def test_mlx_encode_single_with_tiling_updates_progress_per_chunk(self):
method test_mlx_vae_encode_sample_returns_torch_tensor (line 158) | def test_mlx_vae_encode_sample_returns_torch_tensor(self):
method test_mlx_decode_single_raises_when_mlx_vae_missing (line 171) | def test_mlx_decode_single_raises_when_mlx_vae_missing(self):
method test_mlx_encode_single_raises_when_mlx_vae_missing (line 184) | def test_mlx_encode_single_raises_when_mlx_vae_missing(self):
FILE: acestep/core/generation/handler/padding_utils.py
class PaddingMixin (line 7) | class PaddingMixin:
method prepare_padding_info (line 14) | def prepare_padding_info(
FILE: acestep/core/generation/handler/progress.py
class ProgressMixin (line 19) | class ProgressMixin:
method _get_project_root (line 20) | def _get_project_root(self) -> str:
method _load_progress_estimates (line 35) | def _load_progress_estimates(self) -> None:
method _save_progress_estimates (line 47) | def _save_progress_estimates(self) -> None:
method _duration_bucket (line 56) | def _duration_bucket(self, duration_sec: Optional[float]) -> str:
method _update_progress_estimate (line 67) | def _update_progress_estimate(
method _estimate_diffusion_per_step (line 94) | def _estimate_diffusion_per_step(
method _start_diffusion_progress_estimator (line 150) | def _start_diffusion_progress_estimator(
FILE: acestep/core/generation/handler/progress_project_root_test.py
function _load_progress_mixin (line 12) | def _load_progress_mixin():
class TestProgressMixinGetProjectRoot (line 23) | class TestProgressMixinGetProjectRoot(unittest.TestCase):
method _make_host (line 26) | def _make_host(self):
method test_returns_cwd_by_default (line 40) | def test_returns_cwd_by_default(self):
method test_returns_env_var_when_set (line 48) | def test_returns_env_var_when_set(self):
method test_env_var_takes_precedence_over_cwd (line 56) | def test_env_var_takes_precedence_over_cwd(self):
method test_does_not_use_file_location (line 65) | def test_does_not_use_file_location(self):
FILE: acestep/core/generation/handler/prompt_utils.py
class PromptMixin (line 12) | class PromptMixin:
method _format_instruction (line 21) | def _format_instruction(self, instruction: str) -> str:
method _format_lyrics (line 27) | def _format_lyrics(self, lyrics: str, language: str) -> str:
method _pad_sequences (line 31) | def _pad_sequences(
method extract_caption_from_sft_format (line 42) | def extract_caption_from_sft_format(self, caption: str) -> str:
method build_dit_inputs (line 55) | def build_dit_inputs(
method _get_text_hidden_states (line 103) | def _get_text_hidden_states(self, text_prompt: str) -> Tuple[torch.Ten...
method _extract_caption_and_language (line 135) | def _extract_caption_and_language(
FILE: acestep/core/generation/handler/reference_audio_validation_test.py
class ReferenceAudioValidationTests (line 13) | class ReferenceAudioValidationTests(unittest.TestCase):
method test_generate_music_returns_error_for_invalid_reference_audio (line 16) | def test_generate_music_returns_error_for_invalid_reference_audio(self...
FILE: acestep/core/generation/handler/repaint_step_injection.py
function apply_repaint_step_injection (line 6) | def apply_repaint_step_injection(
function build_soft_repaint_mask (line 33) | def build_soft_repaint_mask(
function apply_repaint_boundary_blend (line 84) | def apply_repaint_boundary_blend(
FILE: acestep/core/generation/handler/repaint_step_injection_test.py
class TestApplyRepaintStepInjection (line 14) | class TestApplyRepaintStepInjection(unittest.TestCase):
method setUp (line 17) | def setUp(self):
method test_non_repaint_regions_match_noised_source (line 28) | def test_non_repaint_regions_match_noised_source(self):
method test_repaint_regions_unchanged (line 37) | def test_repaint_regions_unchanged(self):
method test_all_true_mask_is_noop (line 44) | def test_all_true_mask_is_noop(self):
method test_t_zero_returns_clean_source_in_preserved (line 51) | def test_t_zero_returns_clean_source_in_preserved(self):
method test_t_one_returns_pure_noise_in_preserved (line 57) | def test_t_one_returns_pure_noise_in_preserved(self):
class TestBuildSoftRepaintMask (line 64) | class TestBuildSoftRepaintMask(unittest.TestCase):
method test_core_region_is_one (line 67) | def test_core_region_is_one(self):
method test_far_preserved_is_zero (line 73) | def test_far_preserved_is_zero(self):
method test_crossfade_zone_is_monotonic (line 80) | def test_crossfade_zone_is_monotonic(self):
method test_all_true_mask_returns_ones (line 91) | def test_all_true_mask_returns_ones(self):
method test_all_false_mask_returns_zeros (line 96) | def test_all_false_mask_returns_zeros(self):
method test_zero_crossfade_is_hard_mask (line 101) | def test_zero_crossfade_is_hard_mask(self):
method test_crossfade_clamped_at_boundaries (line 107) | def test_crossfade_clamped_at_boundaries(self):
class TestApplyRepaintBoundaryBlend (line 116) | class TestApplyRepaintBoundaryBlend(unittest.TestCase):
method test_preserved_region_uses_source (line 119) | def test_preserved_region_uses_source(self):
method test_core_repaint_uses_generated (line 129) | def test_core_repaint_uses_generated(self):
method test_full_repaint_mask_returns_generated (line 138) | def test_full_repaint_mask_returns_generated(self):
method test_blending_zone_is_interpolated (line 146) | def test_blending_zone_is_interpolated(self):
FILE: acestep/core/generation/handler/repaint_waveform_splice.py
function _build_waveform_crossfade_mask (line 14) | def _build_waveform_crossfade_mask(
function apply_repaint_waveform_splice (line 54) | def apply_repaint_waveform_splice(
FILE: acestep/core/generation/handler/repaint_waveform_splice_test.py
class TestBuildWaveformCrossfadeMask (line 13) | class TestBuildWaveformCrossfadeMask(unittest.TestCase):
method test_mask_ones_inside_repaint_region (line 16) | def test_mask_ones_inside_repaint_region(self):
method test_crossfade_ramp_at_left_boundary (line 22) | def test_crossfade_ramp_at_left_boundary(self):
method test_crossfade_ramp_at_right_boundary (line 31) | def test_crossfade_ramp_at_right_boundary(self):
method test_crossfade_clamps_to_boundaries (line 40) | def test_crossfade_clamps_to_boundaries(self):
method test_zero_crossfade_is_hard_step (line 46) | def test_zero_crossfade_is_hard_step(self):
class TestApplyRepaintWaveformSplice (line 53) | class TestApplyRepaintWaveformSplice(unittest.TestCase):
method _make_tensors (line 56) | def _make_tensors(self, B=1, C=2, samples=4800):
method test_non_repaint_regions_match_src (line 61) | def test_non_repaint_regions_match_src(self):
method test_repaint_region_uses_pred (line 71) | def test_repaint_region_uses_pred(self):
method test_crossfade_produces_intermediate_values (line 80) | def test_crossfade_produces_intermediate_values(self):
method test_full_repaint_returns_pred_unchanged (line 91) | def test_full_repaint_returns_pred_unchanged(self):
method test_length_mismatch_pred_longer (line 98) | def test_length_mismatch_pred_longer(self):
method test_length_mismatch_src_longer (line 107) | def test_length_mismatch_src_longer(self):
method test_batch_independent_splice (line 115) | def test_batch_independent_splice(self):
method test_zero_crossfade_duration (line 129) | def test_zero_crossfade_duration(self):
FILE: acestep/core/generation/handler/resolve_repaint_config_test.py
class TestResolveRepaintConfig (line 8) | class TestResolveRepaintConfig(unittest.TestCase):
method test_aggressive_returns_zeros (line 14) | def test_aggressive_returns_zeros(self):
method test_conservative_returns_max (line 20) | def test_conservative_returns_max(self):
method test_balanced_half (line 26) | def test_balanced_half(self):
method test_balanced_zero_equals_conservative (line 32) | def test_balanced_zero_equals_conservative(self):
method test_balanced_one_equals_aggressive (line 39) | def test_balanced_one_equals_aggressive(self):
method test_strength_clamped_above_one (line 46) | def test_strength_clamped_above_one(self):
method test_strength_clamped_below_zero (line 50) | def test_strength_clamped_below_zero(self):
method test_default_args (line 54) | def test_default_args(self):
FILE: acestep/core/generation/handler/service_generate.py
class ServiceGenerateMixin (line 13) | class ServiceGenerateMixin:
method service_generate (line 21) | def service_generate(
FILE: acestep/core/generation/handler/service_generate_execute.py
class ServiceGenerateExecuteMixin (line 10) | class ServiceGenerateExecuteMixin:
method _unpack_service_processed_data (line 13) | def _unpack_service_processed_data(self, processed_data: Tuple[Any, .....
method _resolve_service_seed_param (line 58) | def _resolve_service_seed_param(self, seed_list: Optional[List[int]]) ...
method _build_service_generate_kwargs (line 64) | def _build_service_generate_kwargs(
method _execute_service_generate_diffusion (line 118) | def _execute_service_generate_diffusion(
FILE: acestep/core/generation/handler/service_generate_execute_test.py
class _Host (line 12) | class _Host(ServiceGenerateExecuteMixin, ServiceGenerateOutputsMixin):
method __init__ (line 15) | def __init__(self):
class ServiceGenerateExecuteMixinTests (line 21) | class ServiceGenerateExecuteMixinTests(unittest.TestCase):
method test_build_generate_kwargs_adds_timesteps_tensor (line 24) | def test_build_generate_kwargs_adds_timesteps_tensor(self):
method test_attach_service_outputs_persists_required_fields (line 62) | def test_attach_service_outputs_persists_required_fields(self):
method test_resolve_seed_param_none_uses_random_seed (line 87) | def test_resolve_seed_param_none_uses_random_seed(self):
FILE: acestep/core/generation/handler/service_generate_outputs.py
class ServiceGenerateOutputsMixin (line 8) | class ServiceGenerateOutputsMixin:
method _attach_service_generate_outputs (line 11) | def _attach_service_generate_outputs(
FILE: acestep/core/generation/handler/service_generate_request.py
class ServiceGenerateRequestMixin (line 15) | class ServiceGenerateRequestMixin:
method _build_service_seed_list (line 18) | def _build_service_seed_list(
method _normalize_service_generate_inputs (line 36) | def _normalize_service_generate_inputs(
FILE: acestep/core/generation/handler/service_generate_request_test.py
class _Host (line 10) | class _Host(ServiceGenerateRequestMixin):
method __init__ (line 13) | def __init__(self, is_turbo: bool):
class ServiceGenerateRequestMixinTests (line 20) | class ServiceGenerateRequestMixinTests(unittest.TestCase):
method test_normalize_inputs_clamps_turbo_steps_and_expands_lists (line 23) | def test_normalize_inputs_clamps_turbo_steps_and_expands_lists(self):
method test_build_service_seed_list_duplicates_scalar_seed (line 50) | def test_build_service_seed_list_duplicates_scalar_seed(self):
method test_seed_list_shorter_than_batch_gets_padded (line 71) | def test_seed_list_shorter_than_batch_gets_padded(self):
method test_seed_list_longer_than_batch_gets_truncated (line 90) | def test_seed_list_longer_than_batch_gets_truncated(self):
method test_lyrics_longer_than_batch_get_truncated (line 108) | def test_lyrics_longer_than_batch_get_truncated(self):
method test_batch_size_at_maximum_is_not_clamped (line 126) | def test_batch_size_at_maximum_is_not_clamped(self):
method test_batch_size_exceeds_maximum_gets_clamped (line 147) | def test_batch_size_exceeds_maximum_gets_clamped(self):
method test_batch_size_clamping_with_seed_list (line 172) | def test_batch_size_clamping_with_seed_list(self):
method test_batch_size_below_maximum_is_not_affected (line 196) | def test_batch_size_below_maximum_is_not_affected(self):
method test_batch_size_clamping_truncates_all_list_fields (line 217) | def test_batch_size_clamping_truncates_all_list_fields(self):
method test_batch_size_clamping_with_single_value_fields (line 257) | def test_batch_size_clamping_with_single_value_fields(self):
FILE: acestep/core/generation/handler/service_generate_test.py
function _load_service_generate_module (line 15) | def _load_service_generate_module():
class _Host (line 59) | class _Host(ServiceGenerateMixin):
method __init__ (line 66) | def __init__(self):
method _normalize_service_generate_inputs (line 92) | def _normalize_service_generate_inputs(self, **kwargs):
method __getattr__ (line 99) | def __getattr__(self, name):
class ServiceGenerateMixinTests (line 112) | class ServiceGenerateMixinTests(unittest.TestCase):
method test_service_generate_orchestrates_helpers_and_returns_attached_outputs (line 115) | def test_service_generate_orchestrates_helpers_and_returns_attached_ou...
method test_service_generate_forwards_runtime_controls_to_build_and_execute (line 127) | def test_service_generate_forwards_runtime_controls_to_build_and_execu...
FILE: acestep/core/generation/handler/task_utils.py
class TaskUtilsMixin (line 12) | class TaskUtilsMixin:
method prepare_seeds (line 19) | def prepare_seeds(
method generate_instruction (line 65) | def generate_instruction(
method determine_task_type (line 99) | def determine_task_type(self, task_type, audio_code_string):
method create_target_wavs (line 115) | def create_target_wavs(self, duration_seconds: float) -> torch.Tensor:
FILE: acestep/core/generation/handler/task_utils_test.py
class _Host (line 8) | class _Host(TaskUtilsMixin):
class DetermineTaskTypeTests (line 12) | class DetermineTaskTypeTests(unittest.TestCase):
method setUp (line 15) | def setUp(self):
method test_repaint_task_enables_repainting (line 18) | def test_repaint_task_enables_repainting(self):
method test_lego_task_enables_repainting_for_chunk_mask (line 26) | def test_lego_task_enables_repainting_for_chunk_mask(self):
method test_cover_task_is_not_repaint (line 39) | def test_cover_task_is_not_repaint(self):
method test_text2music_task_is_not_repaint (line 47) | def test_text2music_task_is_not_repaint(self):
method test_audio_codes_upgrade_task_to_cover (line 55) | def test_audio_codes_upgrade_task_to_cover(self):
method test_lego_with_audio_codes_enables_repainting (line 65) | def test_lego_with_audio_codes_enables_repainting(self):
FILE: acestep/core/generation/handler/training_preset.py
class TrainingPresetMixin (line 6) | class TrainingPresetMixin:
method switch_to_training_preset (line 9) | def switch_to_training_preset(self) -> Tuple[str, bool]:
FILE: acestep/core/generation/handler/training_preset_test.py
function _load_training_preset_module (line 10) | def _load_training_preset_module():
class _Host (line 42) | class _Host(TrainingPresetMixin):
method __init__ (line 45) | def __init__(self):
method initialize_service (line 52) | def initialize_service(self, **kwargs):
class TrainingPresetMixinTests (line 58) | class TrainingPresetMixinTests(unittest.TestCase):
method test_switch_to_training_preset_returns_already_safe_when_unquantized (line 61) | def test_switch_to_training_preset_returns_already_safe_when_unquantiz...
method test_switch_to_training_preset_fails_without_last_init_params (line 69) | def test_switch_to_training_preset_fails_without_last_init_params(self):
method test_switch_to_training_preset_reinitializes_without_quantization (line 78) | def test_switch_to_training_preset_reinitializes_without_quantization(...
method test_switch_to_training_preset_returns_failure_on_reinit_error (line 108) | def test_switch_to_training_preset_returns_failure_on_reinit_error(self):
method test_switch_to_training_preset_passes_none_when_prefer_source_absent (line 132) | def test_switch_to_training_preset_passes_none_when_prefer_source_abse...
method test_switch_to_training_preset_does_not_mutate_last_init_params (line 155) | def test_switch_to_training_preset_does_not_mutate_last_init_params(se...
FILE: acestep/core/generation/handler/vae_decode.py
class VaeDecodeMixin (line 9) | class VaeDecodeMixin:
method tiled_decode (line 16) | def tiled_decode(
method _tiled_decode_cpu_fallback (line 87) | def _tiled_decode_cpu_fallback(self, latents):
method _decode_on_cpu (line 103) | def _decode_on_cpu(self, latents):
FILE: acestep/core/generation/handler/vae_decode_chunks.py
class VaeDecodeChunksMixin (line 10) | class VaeDecodeChunksMixin:
method _tiled_decode_inner (line 13) | def _tiled_decode_inner(self, latents, chunk_size, overlap, offload_wa...
method _tiled_decode_gpu (line 87) | def _tiled_decode_gpu(self, latents, stride, overlap, num_steps):
method _tiled_decode_offload_cpu (line 118) | def _tiled_decode_offload_cpu(self, latents, bsz, latent_frames, strid...
FILE: acestep/core/generation/handler/vae_decode_chunks_test.py
class VaeDecodeChunksMixinTests (line 10) | class VaeDecodeChunksMixinTests(unittest.TestCase):
method test_batch_sequential_decode_for_multi_sample_input (line 13) | def test_batch_sequential_decode_for_multi_sample_input(self):
method test_direct_decode_for_short_latents (line 20) | def test_direct_decode_for_short_latents(self):
method test_overlap_adjustment_reduces_invalid_overlap (line 27) | def test_overlap_adjustment_reduces_invalid_overlap(self):
method test_oom_fallback_gpu_to_offload_path (line 42) | def test_oom_fallback_gpu_to_offload_path(self):
method test_oom_fallback_chain_reaches_decode_on_cpu (line 62) | def test_oom_fallback_chain_reaches_decode_on_cpu(self):
FILE: acestep/core/generation/handler/vae_decode_mixin_test.py
class VaeDecodeMixinTests (line 10) | class VaeDecodeMixinTests(unittest.TestCase):
method test_tiled_decode_reduces_mps_chunk_and_overlap (line 13) | def test_tiled_decode_reduces_mps_chunk_and_overlap(self):
method test_tiled_decode_mps_runtime_failure_uses_cpu_fallback (line 22) | def test_tiled_decode_mps_runtime_failure_uses_cpu_fallback(self):
method test_tiled_decode_uses_mlx_fast_path_when_available (line 35) | def test_tiled_decode_uses_mlx_fast_path_when_available(self):
method test_tiled_decode_falls_back_when_mlx_decode_fails (line 43) | def test_tiled_decode_falls_back_when_mlx_decode_fails(self):
method test_tiled_decode_non_mps_runtime_error_is_raised (line 58) | def test_tiled_decode_non_mps_runtime_error_is_raised(self):
FILE: acestep/core/generation/handler/vae_decode_test_helpers.py
class _DecodeOutput (line 9) | class _DecodeOutput:
method __init__ (line 12) | def __init__(self, sample: torch.Tensor):
class _FakeVae (line 17) | class _FakeVae:
method __init__ (line 20) | def __init__(self, decode_fn=None):
method parameters (line 25) | def parameters(self):
method cpu (line 29) | def cpu(self):
method float (line 33) | def float(self):
method to (line 37) | def to(self, target):
method decode (line 42) | def decode(self, latents: torch.Tensor):
class _DecodeHost (line 50) | class _DecodeHost(VaeDecodeMixin):
method __init__ (line 53) | def __init__(self):
method _get_auto_decode_chunk_size (line 61) | def _get_auto_decode_chunk_size(self):
method _should_offload_wav_to_cpu (line 65) | def _should_offload_wav_to_cpu(self):
method _tiled_decode_inner (line 69) | def _tiled_decode_inner(self, latents, chunk_size, overlap, offload_wa...
method _tiled_decode_cpu_fallback (line 77) | def _tiled_decode_cpu_fallback(self, latents):
method _mlx_vae_decode (line 82) | def _mlx_vae_decode(self, latents):
class _ChunksHost (line 88) | class _ChunksHost(VaeDecodeChunksMixin):
method __init__ (line 91) | def __init__(self):
method _empty_cache (line 99) | def _empty_cache(self):
method _decode_on_cpu (line 103) | def _decode_on_cpu(self, latents):
FILE: acestep/core/generation/handler/vae_encode.py
class VaeEncodeMixin (line 12) | class VaeEncodeMixin:
method tiled_encode (line 15) | def tiled_encode(self, audio, chunk_size=None, overlap=None, offload_l...
FILE: acestep/core/generation/handler/vae_encode_chunks.py
class VaeEncodeChunksMixin (line 7) | class VaeEncodeChunksMixin:
method _tiled_encode_gpu (line 10) | def _tiled_encode_gpu(self, audio, batch_size, samples, stride, overla...
method _tiled_encode_offload_cpu (line 42) | def _tiled_encode_offload_cpu(self, audio, batch_size, samples, stride...
FILE: acestep/core/generation/handler/vae_encode_test.py
class _Dist (line 11) | class _Dist:
method __init__ (line 14) | def __init__(self, sample):
method sample (line 18) | def sample(self):
class _EncOut (line 23) | class _EncOut:
method __init__ (line 26) | def __init__(self, sample):
class _Vae (line 31) | class _Vae:
method __init__ (line 34) | def __init__(self, fn=None):
method encode (line 39) | def encode(self, audio_chunk):
class _Host (line 47) | class _Host(VaeEncodeMixin, VaeEncodeChunksMixin):
method __init__ (line 50) | def __init__(self):
method _get_effective_mps_memory_gb (line 59) | def _get_effective_mps_memory_gb(self):
method _mlx_vae_encode_sample (line 63) | def _mlx_vae_encode_sample(self, audio):
class VaeEncodeMixinTests (line 69) | class VaeEncodeMixinTests(unittest.TestCase):
method test_tiled_encode_uses_mlx_path_when_available (line 72) | def test_tiled_encode_uses_mlx_path_when_available(self):
method test_tiled_encode_direct_path_for_short_audio (line 80) | def test_tiled_encode_direct_path_for_short_audio(self):
method test_tiled_encode_uses_offload_path (line 86) | def test_tiled_encode_uses_offload_path(self):
method test_tiled_encode_rejects_invalid_stride (line 101) | def test_tiled_encode_rejects_invalid_stride(self):
method test_tiled_encode_routes_to_gpu_chunk_path (line 107) | def test_tiled_encode_routes_to_gpu_chunk_path(self):
method test_tiled_encode_gpu_and_offload_outputs_match (line 122) | def test_tiled_encode_gpu_and_offload_outputs_match(self):
method test_tiled_encode_offload_returns_cpu_tensor (line 136) | def test_tiled_encode_offload_returns_cpu_tensor(self):
FILE: acestep/core/lora/introspection.py
function collect_adapter_names (line 8) | def collect_adapter_names(decoder: Any) -> list[str]:
function is_lora_like_module (line 77) | def is_lora_like_module(name: str, module: Any) -> bool:
function read_adapter_value (line 93) | def read_adapter_value(value: Any, adapter: str) -> Any:
function is_peft_factor_set_scale_module (line 109) | def is_peft_factor_set_scale_module(module: Any) -> bool:
function get_peft_initial_scale (line 114) | def get_peft_initial_scale(
FILE: acestep/core/lora/registry.py
function build_lora_registry (line 13) | def build_lora_registry(
FILE: acestep/core/lora/scaling.py
function _inc (line 10) | def _inc(store: dict[str, int], key: str) -> None:
function apply_scale_to_adapter (line 14) | def apply_scale_to_adapter(
FILE: acestep/core/lora/service.py
class LoraService (line 11) | class LoraService:
method __init__ (line 18) | def __init__(
method bind_decoder (line 33) | def bind_decoder(self, decoder: Any | None) -> None:
method set_hooks (line 36) | def set_hooks(
method discover_adapter_names (line 44) | def discover_adapter_names(self) -> list[str]:
method _keep_adapter_agnostic_targets (line 50) | def _keep_adapter_agnostic_targets(registry: dict[str, dict[str, Any]]...
method rebuild_registry (line 63) | def rebuild_registry(self, lora_path: str | None = None) -> tuple[int,...
method ensure_active_adapter (line 91) | def ensure_active_adapter(self) -> str | None:
method set_active_adapter (line 96) | def set_active_adapter(self, adapter_name: str) -> bool:
method apply_scale (line 102) | def apply_scale(self, adapter_name: str, scale: float) -> int:
method registry_snapshot (line 114) | def registry_snapshot(self, max_targets_per_adapter: int = 20) -> dict...
FILE: acestep/core/lora/service_test.py
class FakeDecoder (line 7) | class FakeDecoder:
method __init__ (line 8) | def __init__(self, modules, adapter_names=None):
method named_modules (line 12) | def named_modules(self):
method get_adapter_names (line 15) | def get_adapter_names(self):
class FakeScaleLayerModule (line 21) | class FakeScaleLayerModule:
method __init__ (line 24) | def __init__(self):
method unscale_layer (line 27) | def unscale_layer(self):
method scale_layer (line 30) | def scale_layer(self, value):
class FakeSetScaleFactorModule (line 34) | class FakeSetScaleFactorModule:
method __init__ (line 35) | def __init__(self, scaling):
method set_scale (line 41) | def set_scale(self, adapter_name, factor):
class ExplodingSetScaleModule (line 45) | class ExplodingSetScaleModule:
method set_scale (line 46) | def set_scale(self, adapter_name, factor):
class LoraServiceTests (line 50) | class LoraServiceTests(unittest.TestCase):
method test_rebuild_registry_keeps_adapter_agnostic_targets_without_adapter_names (line 51) | def test_rebuild_registry_keeps_adapter_agnostic_targets_without_adapt...
method test_apply_scale_scale_layer_is_idempotent_with_unscale_layer (line 63) | def test_apply_scale_scale_layer_is_idempotent_with_unscale_layer(self):
method test_set_scale_factor_unanchored_is_reported_and_skipped (line 79) | def test_set_scale_factor_unanchored_is_reported_and_skipped(self):
method test_scaling_scalar_non_numeric_is_skipped_with_warning (line 93) | def test_scaling_scalar_non_numeric_is_skipped_with_warning(self):
method test_target_exception_surfaces_warning (line 116) | def test_target_exception_surfaces_warning(self):
FILE: acestep/core/scoring/_dtw.py
function dtw_cpu (line 13) | def dtw_cpu(x: np.ndarray):
function _backtrace (line 49) | def _backtrace(trace: np.ndarray, N: int, M: int):
function median_filter (line 90) | def median_filter(x: torch.Tensor, filter_width: int) -> torch.Tensor:
FILE: acestep/core/scoring/dit_alignment.py
class TokenTimestamp (line 19) | class TokenTimestamp:
class SentenceTimestamp (line 29) | class SentenceTimestamp:
class MusicStampsAligner (line 39) | class MusicStampsAligner:
method __init__ (line 46) | def __init__(self, tokenizer):
method _apply_bidirectional_consensus (line 55) | def _apply_bidirectional_consensus(
method _preprocess_attention (line 103) | def _preprocess_attention(
method stamps_align_info (line 149) | def stamps_align_info(
method _decode_tokens_incrementally (line 199) | def _decode_tokens_incrementally(self, token_ids: List[int]) -> List[s...
method token_timestamps (line 240) | def token_timestamps(
method _decode_sentence_from_tokens (line 292) | def _decode_sentence_from_tokens(self, tokens: List[TokenTimestamp]) -...
method sentence_timestamps (line 305) | def sentence_timestamps(
method format_lrc (line 375) | def format_lrc(
method get_timestamps_and_lrc (line 411) | def get_timestamps_and_lrc(
FILE: acestep/core/scoring/dit_score.py
class MusicLyricScorer (line 15) | class MusicLyricScorer:
method __init__ (line 23) | def __init__(self, tokenizer: Any):
method _generate_token_type_mask (line 32) | def _generate_token_type_mask(self, token_ids: List[int]) -> np.ndarray:
method _preprocess_attention (line 57) | def _preprocess_attention(
method _compute_alignment_metrics (line 117) | def _compute_alignment_metrics(
method lyrics_alignment_info (line 216) | def lyrics_alignment_info(
method calculate_score (line 269) | def calculate_score(
FILE: acestep/core/scoring/lm_score.py
function pmi_score (line 19) | def pmi_score(log_prob_conditional: float, log_prob_unconditional: float...
function pmi_to_normalized_score (line 42) | def pmi_to_normalized_score(pmi: float, scale: float = 0.1) -> float:
function _load_scoring_model_context (line 71) | def _load_scoring_model_context(llm_handler):
function _get_logits_and_target_for_scoring (line 116) | def _get_logits_and_target_for_scoring(llm_handler, formatted_prompt: str,
function _calculate_topk_recall (line 181) | def _calculate_topk_recall(llm_handler,
function _calculate_metadata_recall (line 235) | def _calculate_metadata_recall(llm_handler,
function _calculate_log_prob (line 263) | def _calculate_log_prob(
function calculate_reward_score (line 292) | def calculate_reward_score(
function calculate_pmi_score_per_condition (line 388) | def calculate_pmi_score_per_condition(
FILE: acestep/core/scoring/scoring_test.py
class DtwCpuTests (line 17) | class DtwCpuTests(unittest.TestCase):
method test_identity_cost_matrix (line 20) | def test_identity_cost_matrix(self):
method test_single_element (line 30) | def test_single_element(self):
method test_rectangular_matrix (line 37) | def test_rectangular_matrix(self):
class MedianFilterTests (line 47) | class MedianFilterTests(unittest.TestCase):
method test_identity_with_width_one (line 50) | def test_identity_with_width_one(self):
method test_smoothing_effect (line 56) | def test_smoothing_effect(self):
method test_short_input_passthrough (line 63) | def test_short_input_passthrough(self):
class PmiScoreTests (line 70) | class PmiScoreTests(unittest.TestCase):
method test_positive_pmi (line 73) | def test_positive_pmi(self):
method test_zero_pmi (line 78) | def test_zero_pmi(self):
method test_negative_pmi (line 83) | def test_negative_pmi(self):
class PmiNormalizedScoreTests (line 89) | class PmiNormalizedScoreTests(unittest.TestCase):
method test_zero_pmi_gives_half (line 92) | def test_zero_pmi_gives_half(self):
method test_positive_pmi_above_half (line 96) | def test_positive_pmi_above_half(self):
method test_negative_pmi_below_half (line 100) | def test_negative_pmi_below_half(self):
method test_bounded_zero_one (line 104) | def test_bounded_zero_one(self):
class RewardScoreTests (line 112) | class RewardScoreTests(unittest.TestCase):
method test_all_components_present (line 115) | def test_all_components_present(self):
method test_no_scores_returns_zero (line 122) | def test_no_scores_returns_zero(self):
method test_caption_only (line 127) | def test_caption_only(self):
method test_metadata_aggregation (line 133) | def test_metadata_aggregation(self):
FILE: acestep/dataset_handler.py
class DatasetHandler (line 14) | class DatasetHandler:
method __init__ (line 22) | def __init__(self):
method import_dataset (line 27) | def import_dataset(self, dataset_type: str) -> str:
method get_item_data (line 46) | def get_item_data(self, *args, **kwargs) -> Tuple:
FILE: acestep/debug_utils.py
function _configure_cpu_threads (line 36) | def _configure_cpu_threads() -> None:
function configure_cpu_threads_if_needed (line 74) | def configure_cpu_threads_if_needed() -> bool:
function _normalize_mode (line 110) | def _normalize_mode(mode: str) -> str:
function is_debug_enabled (line 114) | def is_debug_enabled(mode: str) -> bool:
function is_debug_verbose (line 118) | def is_debug_verbose(mode: str) -> bool:
function debug_log (line 122) | def debug_log(message: Union[str, Callable[[], str]], *, mode: str = TEN...
function get_debug_mode (line 147) | def get_debug_mode(name: str, default: str = "OFF") -> str:
function debug_log_for (line 152) | def debug_log_for(name: str, message: Union[str, Callable[[], str]], *, ...
function debug_start_for (line 158) | def debug_start_for(name: str, label: str) -> Optional[float]:
function debug_end_for (line 164) | def debug_end_for(name: str, label: str, start_ts: Optional[float]) -> N...
function debug_log_verbose_for (line 170) | def debug_log_verbose_for(name: str, message: Union[str, Callable[[], st...
function debug_start_verbose_for (line 178) | def debug_start_verbose_for(name: str, label: str) -> Optional[float]:
function debug_end_verbose_for (line 186) | def debug_end_verbose_for(name: str, label: str, start_ts: Optional[floa...
function debug_start (line 194) | def debug_start(name: str, *, mode: str = TENSOR_DEBUG_MODE, prefix: str...
function debug_end (line 203) | def debug_end(name: str, start_ts: Optional[float], *, mode: str = TENSO...
FILE: acestep/gpu_config.py
function is_mps_platform (line 41) | def is_mps_platform() -> bool:
function is_cuda_available (line 58) | def is_cuda_available() -> bool:
function is_mps_available (line 68) | def is_mps_available() -> bool:
function is_xpu_available (line 78) | def is_xpu_available() -> bool:
function is_rocm_available (line 88) | def is_rocm_available() -> bool:
function cuda_supports_bfloat16 (line 108) | def cuda_supports_bfloat16(device_index: int | None = None) -> bool:
class GPUConfig (line 160) | class GPUConfig:
function get_gpu_memory_gb (line 364) | def get_gpu_memory_gb() -> float:
function _log_gpu_diagnostic_info (line 526) | def _log_gpu_diagnostic_info(torch_module):
function get_gpu_tier (line 631) | def get_gpu_tier(gpu_memory_gb: float) -> str:
function get_gpu_config (line 667) | def get_gpu_config(gpu_memory_gb: Optional[float] = None) -> GPUConfig:
function get_lm_model_size (line 743) | def get_lm_model_size(model_path: str) -> str:
function is_lm_model_size_allowed (line 764) | def is_lm_model_size_allowed(
function find_best_lm_model_on_disk (line 789) | def find_best_lm_model_on_disk(
function get_lm_gpu_memory_ratio (line 825) | def get_lm_gpu_memory_ratio(
function compute_adaptive_config (line 919) | def compute_adaptive_config(total_vram_gb: float, dit_type: str = "turbo...
function get_effective_free_vram_gb (line 1028) | def get_effective_free_vram_gb(device_index: int = 0) -> float:
function get_available_vram_gb (line 1109) | def get_available_vram_gb() -> float:
function estimate_inference_vram (line 1120) | def estimate_inference_vram(
function check_duration_limit (line 1164) | def check_duration_limit(
function check_batch_size_limit (line 1196) | def check_batch_size_limit(
function is_lm_model_supported (line 1228) | def is_lm_model_supported(model_path: str, gpu_config: GPUConfig) -> Tup...
function get_recommended_lm_model (line 1258) | def get_recommended_lm_model(gpu_config: GPUConfig) -> Optional[str]:
function print_gpu_config_info (line 1275) | def print_gpu_config_info(gpu_config: GPUConfig):
function get_gpu_device_name (line 1310) | def get_gpu_device_name() -> str:
function get_gpu_config_for_tier (line 1341) | def get_gpu_config_for_tier(tier: str) -> GPUConfig:
function get_global_gpu_config (line 1405) | def get_global_gpu_config() -> GPUConfig:
function set_global_gpu_config (line 1413) | def set_global_gpu_config(config: GPUConfig):
FILE: acestep/gpu_config_effective_free_vram_test.py
function _make_torch_cuda_mock (line 18) | def _make_torch_cuda_mock(
class GetEffectiveFreeVramGbTests (line 48) | class GetEffectiveFreeVramGbTests(unittest.TestCase):
method _run_with_mock (line 51) | def _run_with_mock(
method test_includes_pytorch_cache_when_device_free_is_zero (line 89) | def test_includes_pytorch_cache_when_device_free_is_zero(self):
method test_sums_device_free_and_allocator_cache (line 109) | def test_sums_device_free_and_allocator_cache(self):
method test_returns_zero_when_fully_allocated_no_cache (line 123) | def test_returns_zero_when_fully_allocated_no_cache(self):
method test_returns_zero_when_cuda_unavailable (line 136) | def test_returns_zero_when_cuda_unavailable(self):
method test_debug_cap_clamps_effective_free (line 146) | def test_debug_cap_clamps_effective_free(self):
FILE: acestep/handler.py
class AceStepHandler (line 61) | class AceStepHandler(
method __init__ (line 102) | def __init__(self):
FILE: acestep/inference.py
function _get_spaces_gpu_decorator (line 23) | def _get_spaces_gpu_decorator(duration=180):
class GenerationParams (line 39) | class GenerationParams:
method to_dict (line 171) | def to_dict(self) -> Dict[str, Any]:
class GenerationConfig (line 177) | class GenerationConfig:
method to_dict (line 200) | def to_dict(self) -> Dict[str, Any]:
class GenerationResult (line 206) | class GenerationResult:
method to_dict (line 227) | def to_dict(self) -> Dict[str, Any]:
class UnderstandResult (line 233) | class UnderstandResult:
method to_dict (line 265) | def to_dict(self) -> Dict[str, Any]:
function _update_metadata_from_lm (line 270) | def _update_metadata_from_lm(
function generate_music (line 318) | def generate_music(
function understand_music (line 814) | def understand_music(
class CreateSampleResult (line 943) | class CreateSampleResult:
method to_dict (line 981) | def to_dict(self) -> Dict[str, Any]:
function create_sample (line 986) | def create_sample(
class FormatSampleResult (line 1120) | class FormatSampleResult:
method to_dict (line 1155) | def to_dict(self) -> Dict[str, Any]:
function format_sample (line 1160) | def format_sample(
FILE: acestep/launcher_compat.py
class LegacyTorchFixDecision (line 13) | class LegacyTorchFixDecision:
function evaluate_legacy_torch_fix (line 27) | def evaluate_legacy_torch_fix(torch_module: Any) -> LegacyTorchFixDecision:
function determine_legacy_torch_fix (line 52) | def determine_legacy_torch_fix(torch_module: Any | None = None) -> Legac...
function legacy_torch_fix_probe_exit_code (line 74) | def legacy_torch_fix_probe_exit_code(torch_module: Any | None = None) ->...
FILE: acestep/launcher_compat_test.py
function _make_torch (line 16) | def _make_torch(
class LauncherCompatDecisionTests (line 31) | class LauncherCompatDecisionTests(unittest.TestCase):
method test_legacy_arch_missing_requires_fix (line 34) | def test_legacy_arch_missing_requires_fix(self) -> None:
method test_legacy_arch_present_skips_fix (line 42) | def test_legacy_arch_present_skips_fix(self) -> None:
method test_modern_gpu_skips_fix_even_if_arch_not_listed (line 50) | def test_modern_gpu_skips_fix_even_if_arch_not_listed(self) -> None:
method test_no_cuda_skips_fix (line 58) | def test_no_cuda_skips_fix(self) -> None:
method test_determine_returns_probe_failed_on_exception (line 66) | def test_determine_returns_probe_failed_on_exception(self) -> None:
method test_probe_exit_code_maps_to_decision (line 77) | def test_probe_exit_code_maps_to_decision(self) -> None:
FILE: acestep/launcher_legacy_torch_fix_test.py
class LauncherLegacyTorchFixTests (line 12) | class LauncherLegacyTorchFixTests(unittest.TestCase):
method _read (line 15) | def _read(self, rel_path: str) -> str:
method test_linux_gradio_launcher_calls_shared_probe (line 19) | def test_linux_gradio_launcher_calls_shared_probe(self) -> None:
method test_linux_api_launcher_calls_shared_probe (line 28) | def test_linux_api_launcher_calls_shared_probe(self) -> None:
method test_windows_gradio_launcher_calls_shared_probe (line 37) | def test_windows_gradio_launcher_calls_shared_probe(self) -> None:
method test_windows_api_launcher_calls_shared_probe (line 52) | def test_windows_api_launcher_calls_shared_probe(self) -> None:
FILE: acestep/llm_backend_compat.py
function _has_working_triton_installation (line 7) | def _has_working_triton_installation() -> bool:
function get_vllm_preflight_warning (line 17) | def get_vllm_preflight_warning(*, device: str, platform: str | None = No...
FILE: acestep/llm_backend_compat_test.py
class VllmBackendCompatTests (line 25) | class VllmBackendCompatTests(unittest.TestCase):
method test_get_vllm_preflight_warning_returns_message_on_windows_without_triton (line 28) | def test_get_vllm_preflight_warning_returns_message_on_windows_without...
method test_get_vllm_preflight_warning_returns_none_outside_windows_cuda (line 41) | def test_get_vllm_preflight_warning_returns_none_outside_windows_cuda(...
class LlmInitializeBackendCompatTests (line 55) | class LlmInitializeBackendCompatTests(unittest.TestCase):
method test_initialize_skips_vllm_when_windows_triton_is_unavailable (line 65) | def test_initialize_skips_vllm_when_windows_triton_is_unavailable(
method test_initialize_falls_back_when_vllm_returns_triton_error (line 117) | def test_initialize_falls_back_when_vllm_returns_triton_error(
FILE: acestep/llm_inference.py
function _warn_if_prerelease_python (line 36) | def _warn_if_prerelease_python():
class LLMHandler (line 48) | class LLMHandler:
method __init__ (line 56) | def __init__(self, persistent_storage_path: Optional[str] = None):
method _clear_accelerator_cache (line 83) | def _clear_accelerator_cache(self) -> None:
method unload (line 117) | def unload(self) -> None:
method _cleanup_torch_distributed_state (line 149) | def _cleanup_torch_distributed_state(self) -> None:
method _get_checkpoint_dir (line 159) | def _get_checkpoint_dir(self) -> str:
method get_available_5hz_lm_models (line 167) | def get_available_5hz_lm_models(self) -> List[str]:
method get_gpu_memory_utilization (line 181) | def get_gpu_memory_utilization(self, model_path: str = None, minimal_g...
method _compute_max_new_tokens (line 231) | def _compute_max_new_tokens(
method _has_meaningful_negative_prompt (line 298) | def _has_meaningful_negative_prompt(self, negative_prompt: str) -> bool:
method _build_logits_processor (line 302) | def _build_logits_processor(self, repetition_penalty: float) -> Logits...
method _setup_constrained_processor (line 309) | def _setup_constrained_processor(
method _build_unconditional_prompt (line 367) | def _build_unconditional_prompt(
method _load_pytorch_model (line 389) | def _load_pytorch_model(self, model_path: str, device: str) -> Tuple[b...
method _apply_top_k_filter (line 406) | def _apply_top_k_filter(self, logits: torch.Tensor, top_k: Optional[in...
method _apply_top_p_filter (line 413) | def _apply_top_p_filter(self, logits: torch.Tensor, top_p: Optional[fl...
method _sample_tokens (line 426) | def _sample_tokens(self, logits: torch.Tensor, temperature: float) -> ...
method _check_eos_token (line 440) | def _check_eos_token(self, tokens: torch.Tensor, eos_token_id: int, pa...
method _update_constrained_processor_state (line 449) | def _update_constrained_processor_state(self, constrained_processor: O...
method _forward_pass (line 455) | def _forward_pass(
method _normalize_batch_input (line 479) | def _normalize_batch_input(self, formatted_prompts: Union[str, List[st...
method initialize (line 487) | def initialize(
method _initialize_5hz_lm_vllm (line 758) | def _initialize_5hz_lm_vllm(self, model_path: str, enforce_eager: bool...
method _run_vllm (line 853) | def _run_vllm(
method _run_pt_single (line 964) | def _run_pt_single(
method _run_pt (line 1124) | def _run_pt(
method has_all_metas (line 1224) | def has_all_metas(self, user_metadata: Optional[Dict[str, Optional[str...
method _format_metadata_as_cot (line 1232) | def _format_metadata_as_cot(self, metadata: Dict[str, Any]) -> str:
method generate_with_stop_condition (line 1261) | def generate_with_stop_condition(
method build_formatted_prompt (line 1647) | def build_formatted_prompt(self, caption: str, lyrics: str = "", is_ne...
method build_formatted_prompt_with_cot (line 1695) | def build_formatted_prompt_with_cot(self, caption: str, lyrics: str, c...
method build_formatted_prompt_for_understanding (line 1757) | def build_formatted_prompt_for_understanding(
method understand_audio_from_codes (line 1805) | def understand_audio_from_codes(
method _extract_lyrics_from_output (line 1905) | def _extract_lyrics_from_output(self, output_text: str) -> str:
method build_formatted_prompt_for_inspiration (line 1943) | def build_formatted_prompt_for_inspiration(
method create_sample_from_query (line 1997) | def create_sample_from_query(
method build_formatted_prompt_for_format (line 2119) | def build_formatted_prompt_for_format(
method format_sample_from_input (line 2171) | def format_sample_from_input(
method generate_from_formatted_prompt (line 2317) | def generate_from_formatted_prompt(
method _generate_with_constrained_decoding (line 2477) | def _generate_with_constrained_decoding(
method _generate_with_cfg_custom (line 2573) | def _generate_with_cfg_custom(
method parse_lm_output (line 2747) | def parse_lm_output(self, output_text: str) -> Tuple[Dict[str, Any], s...
method _is_mlx_available (line 2872) | def _is_mlx_available() -> bool:
method _load_mlx_model (line 2888) | def _load_mlx_model(self, model_path: str) -> Tuple[bool, str]:
method _make_mlx_cache (line 2976) | def _make_mlx_cache(self):
method _run_mlx_batch_native (line 2991) | def _run_mlx_batch_native(
method _run_mlx_single_native (line 3352) | def _run_mlx_single_native(
method _run_mlx_single (line 3675) | def _run_mlx_single(
method _run_mlx (line 3915) | def _run_mlx(
method _load_model_context (line 4054) | def _load_model_context(self):
method get_hf_model_for_scoring (line 4112) | def get_hf_model_for_scoring(self):
FILE: acestep/llm_inference_cache_cleanup_test.py
class LlmAcceleratorCacheCleanupTests (line 18) | class LlmAcceleratorCacheCleanupTests(unittest.TestCase):
method test_syncs_then_clears_cuda (line 21) | def test_syncs_then_clears_cuda(self):
method test_syncs_then_clears_xpu (line 34) | def test_syncs_then_clears_xpu(self):
method test_syncs_then_clears_mps (line 50) | def test_syncs_then_clears_mps(self):
method test_falls_back_to_cuda_when_device_unset (line 69) | def test_falls_back_to_cuda_when_device_unset(self):
method test_noop_when_device_is_cpu (line 82) | def test_noop_when_device_is_cpu(self):
FILE: acestep/llm_inference_cfg_fixes_test.py
function _make_handler (line 32) | def _make_handler() -> "LLMHandler":
function _make_constrained_processor (line 44) | def _make_constrained_processor(state: "FSMState", vocab_size: int = 10)...
function _make_fake_model (line 59) | def _make_fake_model(batch_size: int, vocab_size: int = 10, logit_val: f...
class TestCotCfgScaleFixed (line 75) | class TestCotCfgScaleFixed(unittest.TestCase):
method test_cot_phase_uses_cfg_scale_1 (line 78) | def test_cot_phase_uses_cfg_scale_1(self):
method test_generate_with_stop_condition_forces_cot_cfg_1 (line 122) | def test_generate_with_stop_condition_forces_cot_cfg_1(self):
class TestCfgMaskBeforeCFG (line 175) | class TestCfgMaskBeforeCFG(unittest.TestCase):
method _run_single_step (line 181) | def _run_single_step(
method test_codes_generation_only_samples_valid_tokens (line 228) | def test_codes_generation_only_samples_valid_tokens(self):
method test_non_codes_state_samples_from_full_vocab (line 238) | def test_non_codes_state_samples_from_full_vocab(self):
method test_codes_generation_cfg_applied_to_valid_indices_only (line 248) | def test_codes_generation_cfg_applied_to_valid_indices_only(self):
class TestCfgNanGuard (line 313) | class TestCfgNanGuard(unittest.TestCase):
method test_cfg_nan_replaced_with_neg_inf (line 324) | def test_cfg_nan_replaced_with_neg_inf(self):
class TestPerSequenceEosTracking (line 391) | class TestPerSequenceEosTracking(unittest.TestCase):
method test_generation_stops_when_all_sequences_finish (line 396) | def test_generation_stops_when_all_sequences_finish(self):
method test_finished_sequences_are_forced_to_eos (line 431) | def test_finished_sequences_are_forced_to_eos(self):
FILE: acestep/llm_inference_dist_cleanup_test.py
class LlmDistributedCleanupTests (line 15) | class LlmDistributedCleanupTests(unittest.TestCase):
method test_cleanup_destroys_initialized_process_group (line 18) | def test_cleanup_destroys_initialized_process_group(self):
method test_cleanup_is_noop_when_not_initialized (line 27) | def test_cleanup_is_noop_when_not_initialized(self):
FILE: acestep/llm_inference_enforce_eager_test.py
function _make_handler (line 22) | def _make_handler() -> "LLMHandler":
function _mock_gpu_config (line 27) | def _mock_gpu_config():
class TestEnforceEagerWhenFlashAttnMissing (line 36) | class TestEnforceEagerWhenFlashAttnMissing(unittest.TestCase):
method _run_initialize_with_mocks (line 39) | def _run_initialize_with_mocks(self, flash_attn_available: bool, devic...
method test_enforce_eager_true_when_flash_attn_missing (line 82) | def test_enforce_eager_true_when_flash_attn_missing(self):
method test_enforce_eager_false_when_flash_attn_present (line 91) | def test_enforce_eager_false_when_flash_attn_present(self):
method test_enforce_eager_still_true_for_jetson_even_with_flash_attn (line 99) | def test_enforce_eager_still_true_for_jetson_even_with_flash_attn(self):
FILE: acestep/local_cache.py
class LocalCache (line 19) | class LocalCache:
method __new__ (line 28) | def __new__(cls, cache_dir: Optional[str] = None):
method __init__ (line 37) | def __init__(self, cache_dir: Optional[str] = None):
method set (line 57) | def set(self, name: str, value: Any, ex: Optional[int] = None) -> bool:
method get (line 74) | def get(self, name: str) -> Optional[str]:
method delete (line 78) | def delete(self, name: str) -> int:
method exists (line 82) | def exists(self, name: str) -> bool:
method keys (line 86) | def keys(self, pattern: str = "*") -> list:
method expire (line 97) | def expire(self, name: str, seconds: int) -> bool:
method ttl (line 105) | def ttl(self, name: str) -> int:
method close (line 114) | def close(self):
function get_local_cache (line 120) | def get_local_cache(cache_dir: Optional[str] = None) -> LocalCache:
FILE: acestep/local_cache_thread_safety_test.py
class LocalCacheLockTests (line 9) | class LocalCacheLockTests(unittest.TestCase):
method test_class_level_lock_exists (line 12) | def test_class_level_lock_exists(self):
FILE: acestep/model_downloader.py
function _get_models_source_dir (line 42) | def _get_models_source_dir() -> Path:
function _file_hash (line 47) | def _file_hash(filepath: Path) -> str:
function _check_code_mismatch (line 56) | def _check_code_mismatch(model_name: str, checkpoints_dir) -> List[str]:
function _sync_model_code_files (line 92) | def _sync_model_code_files(model_name: str, checkpoints_dir) -> List[str]:
function _can_access_google (line 136) | def _can_access_google(timeout: float = 3.0) -> bool:
function _download_from_huggingface_internal (line 158) | def _download_from_huggingface_internal(
function _download_from_modelscope_internal (line 186) | def _download_from_modelscope_internal(
function _smart_download (line 210) | def _smart_download(
function get_project_root (line 310) | def get_project_root() -> Path:
function get_checkpoints_dir (line 325) | def get_checkpoints_dir(custom_dir: Optional[str] = None) -> Path:
function _contains_model_weights (line 332) | def _contains_model_weights(model_path: Path) -> bool:
function check_main_model_exists (line 356) | def check_main_model_exists(checkpoints_dir: Optional[Path] = None) -> b...
function check_model_exists (line 375) | def check_model_exists(model_name: str, checkpoints_dir: Optional[Path] ...
function list_available_models (line 398) | def list_available_models() -> Dict[str, str]:
function download_main_model (line 412) | def download_main_model(
function download_submodel (line 463) | def download_submodel(
function download_all_models (line 515) | def download_all_models(
function ensure_main_model (line 555) | def ensure_main_model(
function ensure_lm_model (line 587) | def ensure_lm_model(
function ensure_dit_model (line 633) | def ensure_dit_model(
function print_model_list (line 675) | def print_model_list():
function main (line 698) | def main():
FILE: acestep/model_downloader_test.py
function _load_module (line 12) | def _load_module():
class TestGetProjectRoot (line 23) | class TestGetProjectRoot(unittest.TestCase):
method setUpClass (line 27) | def setUpClass(cls):
method test_returns_cwd_by_default (line 30) | def test_returns_cwd_by_default(self):
method test_returns_env_var_when_set (line 37) | def test_returns_env_var_when_set(self):
method test_env_var_takes_precedence_over_cwd (line 44) | def test_env_var_takes_precedence_over_cwd(self):
method test_does_not_derive_path_from_package_file (line 52) | def test_does_not_derive_path_from_package_file(self):
class TestGetCheckpointsDir (line 64) | class TestGetCheckpointsDir(unittest.TestCase):
method setUpClass (line 68) | def setUpClass(cls):
method test_default_is_checkpoints_under_cwd (line 71) | def test_default_is_checkpoints_under_cwd(self):
method test_custom_dir_overrides_default (line 78) | def test_custom_dir_overrides_default(self):
method test_env_var_is_honoured_as_root (line 84) | def test_env_var_is_honoured_as_root(self):
class TestCheckMainModelExists (line 91) | class TestCheckMainModelExists(unittest.TestCase):
method setUpClass (line 95) | def setUpClass(cls):
method test_returns_false_when_any_component_lacks_weights (line 98) | def test_returns_false_when_any_component_lacks_weights(self):
method test_returns_true_when_all_components_have_weights (line 111) | def test_returns_true_when_all_components_have_weights(self):
method test_returns_true_when_vae_uses_diffusers_weight_filename (line 124) | def test_returns_true_when_vae_uses_diffusers_weight_filename(self):
class TestCheckModelExists (line 141) | class TestCheckModelExists(unittest.TestCase):
method setUpClass (line 145) | def setUpClass(cls):
method test_returns_false_for_partial_model_directory_without_weights (line 148) | def test_returns_false_for_partial_model_directory_without_weights(self):
method test_returns_true_when_model_weights_are_present (line 162) | def test_returns_true_when_model_weights_are_present(self):
FILE: acestep/models/base/apg_guidance.py
class MomentumBuffer (line 5) | class MomentumBuffer:
method __init__ (line 7) | def __init__(self, momentum: float = -0.75):
method update (line 11) | def update(self, update_value: torch.Tensor):
function project (line 16) | def project(
function apg_forward (line 33) | def apg_forward(
function cfg_forward (line 59) | def cfg_forward(cond_output, uncond_output, cfg_strength):
function call_cos_tensor (line 63) | def call_cos_tensor(tensor1, tensor2):
function compute_perpendicular_component (line 80) | def compute_perpendicular_component(latent_diff, latent_hat_uncond):
function adg_forward (line 107) | def adg_forward(
function adg_w_norm_forward (line 191) | def adg_w_norm_forward(
function adg_wo_clip_forward (line 215) | def adg_wo_clip_forward(
FILE: acestep/models/base/configuration_acestep_v15.py
class AceStepConfig (line 25) | class AceStepConfig(PretrainedConfig):
method __init__ (line 148) | def __init__(
FILE: acestep/models/base/modeling_acestep_v15_base.py
function create_4d_mask (line 56) | def create_4d_mask(
function pack_sequences (line 138) | def pack_sequences(hidden1: torch.Tensor, hidden2: torch.Tensor, mask1: ...
function sample_t_r (line 172) | def sample_t_r(batch_size, device, dtype, data_proportion=0.0, timestep_...
class TimestepEmbedding (line 200) | class TimestepEmbedding(nn.Module):
method __init__ (line 208) | def __init__(
method timestep_embedding (line 225) | def timestep_embedding(self, t, dim, max_period=10000):
method forward (line 248) | def forward(self, t):
class AceStepAttention (line 256) | class AceStepAttention(nn.Module):
method __init__ (line 266) | def __init__(self, config: AceStepConfig, layer_idx: int, is_cross_att...
method forward (line 289) | def forward(
class AceStepEncoderLayer (line 374) | class AceStepEncoderLayer(GradientCheckpointingLayer):
method __init__ (line 381) | def __init__(self, config, layer_idx: int):
method forward (line 401) | def forward(
class AceStepDiTLayer (line 443) | class AceStepDiTLayer(GradientCheckpointingLayer):
method __init__ (line 454) | def __init__(self, config: AceStepConfig, layer_idx: int, use_cross_at...
method forward (line 475) | def forward(
class AceStepPreTrainedModel (line 543) | class AceStepPreTrainedModel(PreTrainedModel):
method _init_weights (line 558) | def _init_weights(self, module):
class AceStepLyricEncoder (line 577) | class AceStepLyricEncoder(AceStepPreTrainedModel):
method __init__ (line 585) | def __init__(self, config):
method forward (line 603) | def forward(
class AttentionPooler (line 734) | class AttentionPooler(AceStepPreTrainedModel):
method __init__ (line 743) | def __init__(self, config):
method forward (line 760) | def forward(self,
class AudioTokenDetokenizer (line 862) | class AudioTokenDetokenizer(AceStepPreTrainedModel):
method __init__ (line 870) | def __init__(self, config):
method forward (line 889) | def forward(self,
class AceStepTimbreEncoder (line 997) | class AceStepTimbreEncoder(AceStepPreTrainedModel):
method __init__ (line 1006) | def __init__(self, config):
method unpack_timbre_embeddings (line 1023) | def unpack_timbre_embeddings(self, timbre_embs_packed, refer_audio_ord...
method forward (line 1076) | def forward(
class AceStepAudioTokenizer (line 1181) | class AceStepAudioTokenizer(AceStepPreTrainedModel):
method __init__ (line 1189) | def __init__(self, config):
method forward (line 1206) | def forward(
method tokenize (line 1220) | def tokenize(self, x):
class Lambda (line 1225) | class Lambda(nn.Module):
method __init__ (line 1232) | def __init__(self, func):
method forward (line 1236) | def forward(self, x):
class AceStepDiTModel (line 1240) | class AceStepDiTModel(AceStepPreTrainedModel):
method __init__ (line 1248) | def __init__(self, config: AceStepConfig):
method forward (line 1303) | def forward(
class AceStepConditionEncoder (line 1509) | class AceStepConditionEncoder(AceStepPreTrainedModel):
method __init__ (line 1517) | def __init__(self, config: AceStepConfig):
method forward (line 1527) | def forward(
function _repaint_step_injection (line 1557) | def _repaint_step_injection(xt, clean_src, mask, t_next, noise):
function _repaint_boundary_blend (line 1564) | def _repaint_boundary_blend(x_gen, clean_src, mask, cf_frames):
class AceStepConditionGenerationModel (line 1589) | class AceStepConditionGenerationModel(AceStepPreTrainedModel):
method __init__ (line 1598) | def __init__(self, config: AceStepConfig):
method tokenize (line 1612) | def tokenize(self, x, silence_latent, attention_mask):
method detokenize (line 1625) | def detokenize(self, quantized):
method prepare_condition (line 1639) | def prepare_condition(
method forward (line 1686) | def forward(
method training_losses (line 1762) | def training_losses(self, **kwargs):
method prepare_noise (line 1765) | def prepare_noise(self, context_latents: torch.FloatTensor, seed: Unio...
method get_x0_from_noise (line 1804) | def get_x0_from_noise(self, zt, vt, t):
method renoise (line 1810) | def renoise(self, x, t, noise=None):
method generate_audio (line 1818) | def generate_audio(
function test_forward (line 2044) | def test_forward(model, seed=42):
FILE: acestep/models/mlx/__init__.py
function is_mlx_available (line 10) | def is_mlx_available() -> bool:
function mlx_available (line 28) | def mlx_available() -> bool:
FILE: acestep/models/mlx/dit_convert.py
function convert_decoder_weights (line 11) | def convert_decoder_weights(
function convert_and_load (line 69) | def convert_and_load(
FILE: acestep/models/mlx/dit_generate.py
function get_timestep_schedule (line 34) | def get_timestep_schedule(
function _mlx_apg_forward (line 86) | def _mlx_apg_forward(
function mlx_generate_diffusion (line 119) | def mlx_generate_diffusion(
FILE: acestep/models/mlx/dit_model.py
function _rotate_half (line 16) | def _rotate_half(x: mx.array) -> mx.array:
function _apply_rotary_pos_emb (line 24) | def _apply_rotary_pos_emb(
function _create_sliding_window_mask (line 38) | def _create_sliding_window_mask(
class MLXRotaryEmbedding (line 62) | class MLXRotaryEmbedding(nn.Module):
method __init__ (line 65) | def __init__(self, head_dim: int, max_len: int = 32768, base: float = ...
method __call__ (line 80) | def __call__(self, seq_len: int) -> Tuple[mx.array, mx.array]:
class MLXCrossAttentionCache (line 91) | class MLXCrossAttentionCache:
method __init__ (line 98) | def __init__(self):
method update (line 103) | def update(self, key: mx.array, value: mx.array, layer_idx: int):
method is_updated (line 108) | def is_updated(self, layer_idx: int) -> bool:
method get (line 111) | def get(self, layer_idx: int) -> Tuple[mx.array, mx.array]:
class MLXSwiGLUMLP (line 119) | class MLXSwiGLUMLP(nn.Module):
method __init__ (line 122) | def __init__(self, hidden_size: int, intermediate_size: int):
method __call__ (line 128) | def __call__(self, x: mx.array) -> mx.array:
class MLXAttention (line 132) | class MLXAttention(nn.Module):
method __init__ (line 139) | def __init__(
method _repeat_kv (line 171) | def _repeat_kv(x: mx.array, n_rep: int) -> mx.array:
method __call__ (line 180) | def __call__(
class MLXDiTLayer (line 242) | class MLXDiTLayer(nn.Module):
method __init__ (line 251) | def __init__(
method __call__ (line 302) | def __call__(
class MLXTimestepEmbedding (line 355) | class MLXTimestepEmbedding(nn.Module):
method __init__ (line 358) | def __init__(self, in_channels: int = 256, time_embed_dim: int = 2048,...
method _sinusoidal_embedding (line 369) | def _sinusoidal_embedding(self, t: mx.array, dim: int, max_period: int...
method __call__ (line 392) | def __call__(self, t: mx.array) -> Tuple[mx.array, mx.array]:
class MLXDiTDecoder (line 413) | class MLXDiTDecoder(nn.Module):
method __init__ (line 424) | def __init__(
method _get_sliding_mask (line 510) | def _get_sliding_mask(self, seq_len: int, dtype: mx.Dtype) -> mx.array:
method __call__ (line 517) | def __call__(
method from_config (line 611) | def from_config(cls, config) -> "MLXDiTDecoder":
FILE: acestep/models/mlx/vae_convert.py
function _fuse_weight_norm (line 18) | def _fuse_weight_norm(
function convert_vae_weights (line 37) | def convert_vae_weights(
function convert_and_load (line 135) | def convert_and_load(
FILE: acestep/models/mlx/vae_model.py
class MLXSnake1d (line 24) | class MLXSnake1d(nn.Module):
method __init__ (line 32) | def __init__(self, hidden_dim: int, logscale: bool = True):
method __call__ (line 38) | def __call__(self, x: mx.array) -> mx.array:
class MLXOobleckResidualUnit (line 62) | class MLXOobleckResidualUnit(nn.Module):
method __init__ (line 66) | def __init__(self, dimension: int = 16, dilation: int = 1):
method __call__ (line 77) | def __call__(self, hidden_state: mx.array) -> mx.array:
class MLXOobleckEncoderBlock (line 94) | class MLXOobleckEncoderBlock(nn.Module):
method __init__ (line 97) | def __init__(self, input_dim: int, output_dim: int, stride: int = 1):
method __call__ (line 111) | def __call__(self, hidden_state: mx.array) -> mx.array:
class MLXOobleckDecoderBlock (line 119) | class MLXOobleckDecoderBlock(nn.Module):
method __init__ (line 122) | def __init__(self, input_dim: int, output_dim: int, stride: int = 1):
method __call__ (line 136) | def __call__(self, hidden_state: mx.array) -> mx.array:
class MLXOobleckEncoder (line 149) | class MLXOobleckEncoder(nn.Module):
method __init__ (line 152) | def __init__(
method __call__ (line 181) | def __call__(self, hidden_state: mx.array) -> mx.array:
class MLXOobleckDecoder (line 190) | class MLXOobleckDecoder(nn.Module):
method __init__ (line 193) | def __init__(
method __call__ (line 224) | def __call__(self, hidden_state: mx.array) -> mx.array:
class MLXAutoEncoderOobleck (line 237) | class MLXAutoEncoderOobleck(nn.Module):
method __init__ (line 251) | def __init__(
method encode_and_sample (line 285) | def encode_and_sample(self, audio_nlc: mx.array) -> mx.array:
method encode_mean (line 306) | def encode_mean(self, audio_nlc: mx.array) -> mx.array:
method decode (line 312) | def decode(self, latents_nlc: mx.array) -> mx.array:
method from_pytorch_config (line 326) | def from_pytorch_config(cl
Copy disabled (too large)
Download .json
Condensed preview — 1148 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (11,389K chars).
[
{
"path": ".claude/skills/acestep/SKILL.md",
"chars": 12810,
"preview": "---\nname: acestep\ndescription: Use ACE-Step API to generate music, edit songs, and remix music. Supports text-to-music, "
},
{
"path": ".claude/skills/acestep/api-reference.md",
"chars": 4864,
"preview": "# ACE-Step API Reference\n\n> For debugging and advanced usage only. Normal operations should use `scripts/acestep.sh`.\n\n#"
},
{
"path": ".claude/skills/acestep/scripts/acestep.sh",
"chars": 44554,
"preview": "#!/bin/bash\n#\n# ACE-Step Music Generation CLI (Bash + Curl + jq)\n#\n# Requirements: curl, jq\n#\n# Usage:\n# ./acestep.sh "
},
{
"path": ".claude/skills/acestep/scripts/config.example.json",
"chars": 293,
"preview": "{\n \"api_url\": \"https://api.acemusic.ai\",\n \"api_key\": \"\",\n \"api_mode\": \"completion\",\n \"generation\": {\n \"thinking\":"
},
{
"path": ".claude/skills/acestep-docs/SKILL.md",
"chars": 3268,
"preview": "---\nname: acestep-docs\ndescription: ACE-Step documentation and troubleshooting. Use when users ask about installing ACE-"
},
{
"path": ".claude/skills/acestep-docs/api/API.md",
"chars": 21920,
"preview": "# ACE-Step API Client Documentation\n\n---\n\nThis service provides an HTTP-based asynchronous music generation API.\n\n**Basi"
},
{
"path": ".claude/skills/acestep-docs/api/Openrouter_API.md",
"chars": 15287,
"preview": "# ACE-Step OpenRouter API Documentation\n\n> OpenAI Chat Completions-compatible API for AI music generation\n\n**Base URL:**"
},
{
"path": ".claude/skills/acestep-docs/getting-started/ABOUT.md",
"chars": 3517,
"preview": "# ACE-Step Project Overview\n\n> For installation instructions, see [README.md](README.md)\n\n## Links\n\n- [Project Page](htt"
},
{
"path": ".claude/skills/acestep-docs/getting-started/README.md",
"chars": 6796,
"preview": "# ACE-Step Installation Guide\n\n## Requirements\n\n- Python 3.11\n- CUDA GPU recommended (works on CPU/MPS/MLX but slower)\n\n"
},
{
"path": ".claude/skills/acestep-docs/getting-started/Tutorial.md",
"chars": 46770,
"preview": "# ACE-Step 1.5 Ultimate Guide (Must Read)\n\n---\n\nHello everyone, I'm Gong Junmin, the developer of ACE-Step. Through this"
},
{
"path": ".claude/skills/acestep-docs/guides/ENVIRONMENT_SETUP.md",
"chars": 15030,
"preview": "# Environment Setup Guide\n\nThis guide covers Python environment setup for ACE-Step on Windows, Linux, and macOS.\n\n## Env"
},
{
"path": ".claude/skills/acestep-docs/guides/GPU_COMPATIBILITY.md",
"chars": 5457,
"preview": "# GPU Compatibility Guide\n\nACE-Step 1.5 automatically adapts to your GPU's available VRAM, adjusting generation limits a"
},
{
"path": ".claude/skills/acestep-docs/guides/GRADIO_GUIDE.md",
"chars": 16988,
"preview": "# ACE-Step Gradio Demo User Guide\n\n---\n\nThis guide provides comprehensive documentation for using the ACE-Step Gradio we"
},
{
"path": ".claude/skills/acestep-docs/guides/INFERENCE.md",
"chars": 36899,
"preview": "# ACE-Step Inference API Documentation\n\n---\n\nThis document provides comprehensive documentation for the ACE-Step inferen"
},
{
"path": ".claude/skills/acestep-docs/guides/SCRIPT_CONFIGURATION.md",
"chars": 17294,
"preview": "# Launch Script Configuration Guide\n\nThis guide explains how to configure the startup scripts for ACE-Step across all su"
},
{
"path": ".claude/skills/acestep-docs/guides/UPDATE_AND_BACKUP.md",
"chars": 13709,
"preview": "# Update and Backup Guide\n\n## Overview\n\nAll ACE-Step launch scripts check for updates on startup by default. The update "
},
{
"path": ".claude/skills/acestep-lyrics-transcription/SKILL.md",
"chars": 7487,
"preview": "---\nname: acestep-lyrics-transcription\ndescription: Transcribe audio to timestamped lyrics using OpenAI Whisper or Eleve"
},
{
"path": ".claude/skills/acestep-lyrics-transcription/scripts/acestep-lyrics-transcription.sh",
"chars": 18042,
"preview": "#!/bin/bash\n#\n# acestep-lyrics-transcription.sh - Transcribe audio to timestamped lyrics (LRC/SRT/JSON)\n#\n# Requirements"
},
{
"path": ".claude/skills/acestep-lyrics-transcription/scripts/config.example.json",
"chars": 278,
"preview": "{\n \"provider\": \"elevenlabs\",\n \"output_format\": \"lrc\",\n \"openai\": {\n \"api_key\": \"\",\n \"api_url\": \"https://api.ope"
},
{
"path": ".claude/skills/acestep-simplemv/SKILL.md",
"chars": 7068,
"preview": "---\nname: acestep-simplemv\ndescription: Render music videos from audio files and lyrics using Remotion. Accepts audio + "
},
{
"path": ".claude/skills/acestep-simplemv/scripts/package.json",
"chars": 613,
"preview": "{\n \"name\": \"acestep-video\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"start\""
},
{
"path": ".claude/skills/acestep-simplemv/scripts/remotion.config.ts",
"chars": 115,
"preview": "import {Config} from '@remotion/cli/config';\n\nConfig.setVideoImageFormat('jpeg');\nConfig.setOverwriteOutput(true);\n"
},
{
"path": ".claude/skills/acestep-simplemv/scripts/render-mv.sh",
"chars": 8533,
"preview": "#!/bin/bash\n# render-mv.sh - Render a music video from audio + lyrics\n#\n# Usage:\n# ./render-mv.sh --audio <file> --lyr"
},
{
"path": ".claude/skills/acestep-simplemv/scripts/render.mjs",
"chars": 13120,
"preview": "#!/usr/bin/env node\n\n/**\n * CLI entry point for rendering music videos.\n * \n * Usage:\n * node render.mjs --audio music"
},
{
"path": ".claude/skills/acestep-simplemv/scripts/render.sh",
"chars": 391,
"preview": "#!/bin/bash\n# render.sh - Convenience wrapper for rendering music videos\n#\n# Usage:\n# ./render.sh --audio music.mp3 --"
},
{
"path": ".claude/skills/acestep-simplemv/scripts/src/AudioVisualization.tsx",
"chars": 10766,
"preview": "import React from 'react';\nimport {\n AbsoluteFill,\n Audio,\n Img,\n useCurrentFrame,\n useVideoConfig,\n interpolate,\n"
},
{
"path": ".claude/skills/acestep-simplemv/scripts/src/Root.tsx",
"chars": 770,
"preview": "import React from 'react';\nimport {Composition, CalculateMetadataFunction} from 'remotion';\nimport {AudioVisualization} "
},
{
"path": ".claude/skills/acestep-simplemv/scripts/src/index.ts",
"chars": 105,
"preview": "import {registerRoot} from 'remotion';\nimport {RemotionRoot} from './Root';\n\nregisterRoot(RemotionRoot);\n"
},
{
"path": ".claude/skills/acestep-simplemv/scripts/src/parseLrc.ts",
"chars": 1263,
"preview": "import {LyricLine} from './types';\n\n/**\n * Parse LRC format lyrics into LyricLine array.\n * LRC format: [mm:ss.xx] lyric"
},
{
"path": ".claude/skills/acestep-simplemv/scripts/src/types.ts",
"chars": 1069,
"preview": "export interface LyricLine {\n start: number;\n end: number;\n text: string;\n}\n\nexport interface MVInputProps extends Re"
},
{
"path": ".claude/skills/acestep-simplemv/scripts/tsconfig.json",
"chars": 437,
"preview": "{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ES2022\",\n \"moduleResolution\": \"Bundler\",\n \"lib\": ["
},
{
"path": ".claude/skills/acestep-songwriting/SKILL.md",
"chars": 7819,
"preview": "---\nname: acestep-songwriting\ndescription: Music songwriting guide for ACE-Step. Provides professional knowledge on writ"
},
{
"path": ".claude/skills/acestep-thumbnail/SKILL.md",
"chars": 5149,
"preview": "---\nname: acestep-thumbnail\ndescription: Generate song cover/thumbnail images using Gemini API. Creates artistic images "
},
{
"path": ".claude/skills/acestep-thumbnail/scripts/acestep-thumbnail.sh",
"chars": 9261,
"preview": "#!/bin/bash\n# acestep-thumbnail.sh - Generate song cover/thumbnail images using Gemini API\n#\n# Usage:\n# ./acestep-thum"
},
{
"path": ".claude/skills/acestep-thumbnail/scripts/config.example.json",
"chars": 156,
"preview": "{\n \"api_key\": \"\",\n \"api_url\": \"https://generativelanguage.googleapis.com/v1beta\",\n \"model\": \"gemini-3.1-flash-image-p"
},
{
"path": ".dockerignore",
"chars": 1081,
"preview": "# =============================================================================\n# .dockerignore — ACE-Step 1.5\n# Keep Do"
},
{
"path": ".editorconfig",
"chars": 256,
"preview": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.{bat,"
},
{
"path": ".githooks/pre-push",
"chars": 1406,
"preview": "#!/usr/bin/env sh\nset -eu\n\n# Prevent cross-polluted PR branches by ensuring the current branch is\n# independently based "
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 1210,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n> **📚 Before sub"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 937,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n> **📚 Quick t"
},
{
"path": ".github/codeql-config.yml",
"chars": 1085,
"preview": "# CodeQL configuration for ACE-Step-1.5\n#\n# This project is a local Gradio desktop application for music generation\n# an"
},
{
"path": ".github/copilot-instructions.md",
"chars": 2615,
"preview": "# ACE-Step 1.5 - GitHub Copilot Instructions\n\n## Project Overview\n\nACE-Step 1.5 is an open-source music foundation model"
},
{
"path": ".github/workflows/close-inactive-issues.yml",
"chars": 1018,
"preview": "name: Close inactive issues\n\non:\n schedule:\n # Cron is UTC\n - cron: \"15 6 * * *\"\n workflow_dispatch: {}\n\npermiss"
},
{
"path": ".github/workflows/codeql.yml",
"chars": 4490,
"preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
},
{
"path": ".github/workflows/docs.yml",
"chars": 1129,
"preview": "name: Deploy Documentation\n\non:\n push:\n branches: [main]\n paths:\n - 'docs/**'\n - 'package.json'\n -"
},
{
"path": ".gitignore",
"chars": 5528,
"preview": "#Exclude potential (c) training data\n*_lyrics.txt\n*.mp3\nAlbumArt*.jpg\nFolder.jpg\n\n\ndata/\n*.mp3\n*.wav\n\n# Byte-compiled / "
},
{
"path": "AGENTS.md",
"chars": 7908,
"preview": "# AGENTS.md\n\nGuidance for AI coding agents working in `ace-step/ACE-Step-1.5`.\n\nThis document is aligned with the intent"
},
{
"path": "CONTRIBUTING.md",
"chars": 6156,
"preview": "Hopefully this will provide a simple, easy to understand guide to making safe contributions to the project, happy coding"
},
{
"path": "Dockerfile.jetson",
"chars": 14328,
"preview": "# =============================================================================\n# ACE-Step 1.5 — NVIDIA Jetson Dockerfil"
},
{
"path": "LICENSE",
"chars": 1064,
"preview": "MIT License\n\nCopyright (c) 2026 ACEStep\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof"
},
{
"path": "README-XPU.md",
"chars": 4544,
"preview": "# ACE-Step 1.5 - Intel XPU Setup Guide\n\nQuick start guide for running ACE-Step on Intel Arc GPUs and integrated graphics"
},
{
"path": "README.md",
"chars": 16955,
"preview": "<h1 align=\"center\">ACE-Step 1.5</h1>\n<h1 align=\"center\">Pushing the Boundaries of Open-Source Music Generation</h1>\n<p a"
},
{
"path": "SECURITY.md",
"chars": 962,
"preview": "# Security Policy\n\n## Reporting a Vulnerability\n\nWe take security issues seriously and appreciate responsible disclosure"
},
{
"path": "acestep/__init__.py",
"chars": 24,
"preview": "\"\"\"ACE-Step package.\"\"\"\n"
},
{
"path": "acestep/acestep_v15_pipeline.py",
"chars": 26472,
"preview": "\"\"\"\nACE-Step V1.5 Pipeline\nHandler wrapper connecting model and UI\n\"\"\"\n\nimport os\nimport sys\n\n# Load environment variabl"
},
{
"path": "acestep/api/__init__.py",
"chars": 90,
"preview": "\"\"\"API package intent: external service boundary (transport, auth, request lifecycle).\"\"\"\n"
},
{
"path": "acestep/api/http/__init__.py",
"chars": 78,
"preview": "\"\"\"HTTP package intent: web app assembly, routes, schemas, and middleware.\"\"\"\n"
},
{
"path": "acestep/api/http/audio_route.py",
"chars": 1381,
"preview": "\"\"\"HTTP route for serving generated audio files by path.\"\"\"\n\nfrom __future__ import annotations\n\nfrom pathlib import Pat"
},
{
"path": "acestep/api/http/audio_route_http_test.py",
"chars": 2101,
"preview": "\"\"\"HTTP integration tests for the audio file route.\"\"\"\n\nimport unittest\nfrom pathlib import Path\nfrom unittest import mo"
},
{
"path": "acestep/api/http/audio_route_test.py",
"chars": 2870,
"preview": "\"\"\"Unit tests for audio route registration.\"\"\"\n\nimport asyncio\nimport unittest\nfrom pathlib import Path\n\nfrom fastapi im"
},
{
"path": "acestep/api/http/auth.py",
"chars": 2222,
"preview": "\"\"\"API-key authentication helpers shared across HTTP route registration.\"\"\"\n\nfrom __future__ import annotations\n\nfrom ty"
},
{
"path": "acestep/api/http/auth_test.py",
"chars": 3283,
"preview": "\"\"\"Unit tests for API-key authentication helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport unittest"
},
{
"path": "acestep/api/http/lora_routes.py",
"chars": 6348,
"preview": "\"\"\"LoRA HTTP routes for adapter lifecycle controls.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Call"
},
{
"path": "acestep/api/http/lora_routes_http_test.py",
"chars": 5109,
"preview": "\"\"\"HTTP integration tests for LoRA route registration.\"\"\"\n\nimport unittest\nfrom typing import Any, Dict\n\nfrom fastapi im"
},
{
"path": "acestep/api/http/lora_routes_test.py",
"chars": 5122,
"preview": "\"\"\"Unit tests for LoRA route registration and endpoint behavior.\"\"\"\n\nimport asyncio\nimport unittest\nfrom typing import A"
},
{
"path": "acestep/api/http/model_init_service.py",
"chars": 4828,
"preview": "\"\"\"Blocking model initialization helpers for API model service routes.\"\"\"\n\nfrom __future__ import annotations\n\nimport os"
},
{
"path": "acestep/api/http/model_init_service_test.py",
"chars": 5231,
"preview": "\"\"\"Unit tests for blocking model initialization service helpers.\"\"\"\n\nimport threading\nimport unittest\nfrom types import "
},
{
"path": "acestep/api/http/model_service_routes.py",
"chars": 8518,
"preview": "\"\"\"HTTP routes for service health, model inventory, and on-demand model init.\"\"\"\n\nfrom __future__ import annotations\n\nim"
},
{
"path": "acestep/api/http/model_service_routes_http_test.py",
"chars": 7258,
"preview": "\"\"\"HTTP integration tests for model service routes.\"\"\"\n\nimport asyncio\nimport queue\nimport threading\nimport unittest\nfro"
},
{
"path": "acestep/api/http/model_service_routes_test.py",
"chars": 4537,
"preview": "\"\"\"Unit tests for model service route registration helpers.\"\"\"\n\nimport asyncio\nimport os\nimport queue\nimport unittest\nfr"
},
{
"path": "acestep/api/http/query_result_route.py",
"chars": 2514,
"preview": "\"\"\"HTTP route for querying one or more generation task results.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing impo"
},
{
"path": "acestep/api/http/query_result_route_http_test.py",
"chars": 8374,
"preview": "\"\"\"HTTP integration tests for query-result route behavior.\"\"\"\n\nimport json\nimport time\nimport unittest\nfrom types import"
},
{
"path": "acestep/api/http/query_result_route_test.py",
"chars": 6492,
"preview": "\"\"\"Unit tests for query-result route registration and helper behavior.\"\"\"\n\nimport asyncio\nimport json\nimport time\nimport"
},
{
"path": "acestep/api/http/query_result_service.py",
"chars": 6613,
"preview": "\"\"\"Service helpers for `/query_result` response shaping.\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport time"
},
{
"path": "acestep/api/http/reinitialize_route.py",
"chars": 4669,
"preview": "\"\"\"HTTP route for reinitializing service components after unload flows.\"\"\"\n\nfrom __future__ import annotations\n\nimport o"
},
{
"path": "acestep/api/http/reinitialize_route_http_test.py",
"chars": 3512,
"preview": "\"\"\"HTTP integration tests for the /v1/reinitialize route.\"\"\"\n\nfrom pathlib import Path\nimport unittest\nfrom types import"
},
{
"path": "acestep/api/http/reinitialize_route_test.py",
"chars": 5428,
"preview": "\"\"\"Unit tests for reinitialize route registration.\"\"\"\n\nimport asyncio\nimport unittest\nfrom types import SimpleNamespace\n"
},
{
"path": "acestep/api/http/release_task_audio_paths.py",
"chars": 2651,
"preview": "\"\"\"Audio-path validation and upload persistence helpers for release-task flow.\"\"\"\n\nfrom __future__ import annotations\n\ni"
},
{
"path": "acestep/api/http/release_task_audio_paths_test.py",
"chars": 4205,
"preview": "\"\"\"Unit tests for audio path validation and temp upload persistence helpers.\"\"\"\n\nimport asyncio\nimport os\nimport tempfil"
},
{
"path": "acestep/api/http/release_task_models.py",
"chars": 5486,
"preview": "\"\"\"Pydantic request model definitions used by the `/release_task` flow.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typ"
},
{
"path": "acestep/api/http/release_task_models_test.py",
"chars": 1542,
"preview": "\"\"\"Unit tests for release-task request model defaults and compatibility flags.\"\"\"\n\nimport unittest\n\nfrom acestep.api.htt"
},
{
"path": "acestep/api/http/release_task_param_parser.py",
"chars": 6190,
"preview": "\"\"\"Canonical parameter aliasing and parsing helpers for release-task requests.\"\"\"\n\nfrom __future__ import annotations\n\ni"
},
{
"path": "acestep/api/http/release_task_param_parser_test.py",
"chars": 2731,
"preview": "\"\"\"Unit tests for canonical request parameter parsing helpers.\"\"\"\n\nimport unittest\n\nfrom acestep.api.http.release_task_p"
},
{
"path": "acestep/api/http/release_task_request_builder.py",
"chars": 4831,
"preview": "\"\"\"Helpers for building release-task request models from parsed inputs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typ"
},
{
"path": "acestep/api/http/release_task_request_builder_test.py",
"chars": 5134,
"preview": "\"\"\"Unit tests for release-task request-model builder helpers.\"\"\"\n\nimport unittest\nfrom types import SimpleNamespace\n\nfro"
},
{
"path": "acestep/api/http/release_task_request_parser.py",
"chars": 8290,
"preview": "\"\"\"Request parsing helpers for the ``/release_task`` HTTP route.\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimp"
},
{
"path": "acestep/api/http/release_task_request_parser_test.py",
"chars": 9773,
"preview": "\"\"\"Unit tests for release-task request parsing helper.\"\"\"\n\nimport asyncio\nimport json\nimport unittest\nfrom types import "
},
{
"path": "acestep/api/http/release_task_route.py",
"chars": 3476,
"preview": "\"\"\"HTTP route registration for ``/release_task`` task-submission endpoint.\"\"\"\n\nfrom __future__ import annotations\n\nimpor"
},
{
"path": "acestep/api/http/release_task_route_http_test.py",
"chars": 6086,
"preview": "\"\"\"HTTP integration tests for release-task route registration.\"\"\"\n\nimport asyncio\nimport time\nimport unittest\nfrom types"
},
{
"path": "acestep/api/http/sample_format_routes.py",
"chars": 7202,
"preview": "\"\"\"HTTP routes for random sample creation and input formatting.\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimpo"
},
{
"path": "acestep/api/http/sample_format_routes_http_test.py",
"chars": 4105,
"preview": "\"\"\"HTTP integration tests for sample/format routes.\"\"\"\n\nimport threading\nimport unittest\nfrom types import SimpleNamespa"
},
{
"path": "acestep/api/http/sample_format_routes_test.py",
"chars": 5480,
"preview": "\"\"\"Unit tests for sample/format route registration.\"\"\"\n\nimport asyncio\nimport json\nimport threading\nimport unittest\nfrom"
},
{
"path": "acestep/api/job_analysis_runtime.py",
"chars": 4307,
"preview": "\"\"\"Analysis-mode runtime helpers for API job generation.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing i"
},
{
"path": "acestep/api/job_analysis_runtime_test.py",
"chars": 7133,
"preview": "\"\"\"Unit tests for analysis-only runtime helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport unittest\nfrom "
},
{
"path": "acestep/api/job_blocking_generation.py",
"chars": 7598,
"preview": "\"\"\"Blocking generation orchestration helper for API jobs.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport time\n"
},
{
"path": "acestep/api/job_blocking_generation_test.py",
"chars": 7613,
"preview": "\"\"\"Unit tests for blocking generation orchestration helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfrom"
},
{
"path": "acestep/api/job_execution_runtime.py",
"chars": 4233,
"preview": "\"\"\"Async job execution runtime helper for API queue workers.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimpo"
},
{
"path": "acestep/api/job_execution_runtime_test.py",
"chars": 7746,
"preview": "\"\"\"Unit tests for async job execution runtime helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport unit"
},
{
"path": "acestep/api/job_generation_runtime.py",
"chars": 3832,
"preview": "\"\"\"Runtime helpers for executing generation runs and aggregating outputs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom t"
},
{
"path": "acestep/api/job_generation_runtime_test.py",
"chars": 3788,
"preview": "\"\"\"Unit tests for generation runtime execution helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfrom type"
},
{
"path": "acestep/api/job_generation_setup.py",
"chars": 7765,
"preview": "\"\"\"Generation parameter/config assembly helpers for API job execution.\"\"\"\n\nfrom __future__ import annotations\n\nfrom data"
},
{
"path": "acestep/api/job_generation_setup_test.py",
"chars": 6077,
"preview": "\"\"\"Unit tests for generation setup assembly helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfrom types "
},
{
"path": "acestep/api/job_llm_preparation.py",
"chars": 340,
"preview": "\"\"\"Compatibility facade for LLM request preparation helpers.\"\"\"\n\nfrom acestep.api.llm_generation_inputs import PreparedL"
},
{
"path": "acestep/api/job_llm_preparation_test.py",
"chars": 4838,
"preview": "\"\"\"Unit tests for LLM readiness and request-input preparation helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport os"
},
{
"path": "acestep/api/job_model_selection.py",
"chars": 2595,
"preview": "\"\"\"Model selection helpers for per-job DiT handler routing.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import A"
},
{
"path": "acestep/api/job_model_selection_test.py",
"chars": 3391,
"preview": "\"\"\"Unit tests for per-job model handler selection helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfrom t"
},
{
"path": "acestep/api/job_result_payload.py",
"chars": 4150,
"preview": "\"\"\"Response payload helpers for successful music generation jobs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing im"
},
{
"path": "acestep/api/job_result_payload_test.py",
"chars": 3142,
"preview": "\"\"\"Unit tests for generation success response payload helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfr"
},
{
"path": "acestep/api/job_runtime_state.py",
"chars": 3578,
"preview": "\"\"\"Runtime state helpers for API job execution flow.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing impor"
},
{
"path": "acestep/api/job_runtime_state_test.py",
"chars": 3184,
"preview": "\"\"\"Unit tests for runtime job-state helper functions.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport os\ni"
},
{
"path": "acestep/api/jobs/__init__.py",
"chars": 76,
"preview": "\"\"\"Jobs package: async task execution, queueing, and job state tracking.\"\"\"\n"
},
{
"path": "acestep/api/jobs/local_cache_updates.py",
"chars": 5387,
"preview": "\"\"\"Helpers for writing API job state into the local cache backend.\"\"\"\n\nfrom __future__ import annotations\n\nimport time\nf"
},
{
"path": "acestep/api/jobs/local_cache_updates_test.py",
"chars": 7358,
"preview": "\"\"\"Unit tests for local-cache job payload update helpers.\"\"\"\n\nimport unittest\nfrom types import SimpleNamespace\n\nfrom ac"
},
{
"path": "acestep/api/jobs/models.py",
"chars": 1503,
"preview": "\"\"\"Job models for API queue state and response payloads.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any,"
},
{
"path": "acestep/api/jobs/store.py",
"chars": 7058,
"preview": "\"\"\"In-memory job store and JSON persistence helpers for API jobs.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio"
},
{
"path": "acestep/api/jobs/store_test.py",
"chars": 4789,
"preview": "\"\"\"Unit tests for API job store state tracking and persistence helpers.\"\"\"\n\nimport json\nimport os\nimport time\nimport uni"
},
{
"path": "acestep/api/jobs/test_fakes.py",
"chars": 1951,
"preview": "\"\"\"Shared unittest fakes for API job helper tests.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Optio"
},
{
"path": "acestep/api/jobs/worker_loops.py",
"chars": 2760,
"preview": "\"\"\"Queue worker loop helpers for API job processing.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nfrom typing "
},
{
"path": "acestep/api/jobs/worker_loops_test.py",
"chars": 6938,
"preview": "\"\"\"Unit tests for queue worker loop helper functions.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport unit"
},
{
"path": "acestep/api/lifespan_runtime.py",
"chars": 4827,
"preview": "\"\"\"Lifespan bootstrap helpers for API server runtime state initialization.\"\"\"\n\nfrom __future__ import annotations\n\nimpor"
},
{
"path": "acestep/api/lifespan_runtime_test.py",
"chars": 4299,
"preview": "\"\"\"Unit tests for lifespan runtime bootstrap helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport unittest\nf"
},
{
"path": "acestep/api/llm_generation_inputs.py",
"chars": 7702,
"preview": "\"\"\"LLM-driven request input preparation helpers for generation jobs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom datacl"
},
{
"path": "acestep/api/llm_readiness.py",
"chars": 3607,
"preview": "\"\"\"LLM readiness helper for generation requests.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing import An"
},
{
"path": "acestep/api/log_capture.py",
"chars": 1857,
"preview": "\"\"\"Log capture utilities for API progress/status endpoints.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import A"
},
{
"path": "acestep/api/log_capture_test.py",
"chars": 2038,
"preview": "\"\"\"Unit tests for API log capture utilities.\"\"\"\n\nfrom __future__ import annotations\n\nimport io\nimport unittest\n\nfrom ace"
},
{
"path": "acestep/api/model_download.py",
"chars": 4973,
"preview": "\"\"\"Model auto-download helpers extracted from API server runtime.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\n\n\nMO"
},
{
"path": "acestep/api/model_download_test.py",
"chars": 5933,
"preview": "\"\"\"Unit tests for API model auto-download helper functions.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport typ"
},
{
"path": "acestep/api/route_setup.py",
"chars": 5849,
"preview": "\"\"\"Application route and middleware registration helpers for API server.\"\"\"\n\nfrom __future__ import annotations\n\nfrom fu"
},
{
"path": "acestep/api/route_setup_test.py",
"chars": 3906,
"preview": "\"\"\"Unit tests for API route setup helper wiring.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfrom unittest.m"
},
{
"path": "acestep/api/runtime_helpers.py",
"chars": 6429,
"preview": "\"\"\"Runtime helper functions used by API training and model orchestration paths.\"\"\"\n\nfrom __future__ import annotations\n\n"
},
{
"path": "acestep/api/runtime_helpers_test.py",
"chars": 9176,
"preview": "\"\"\"Unit tests for API runtime helper utilities.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport threading\nimpor"
},
{
"path": "acestep/api/server_cli.py",
"chars": 3304,
"preview": "\"\"\"CLI bootstrap helpers for launching the API server process.\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\ni"
},
{
"path": "acestep/api/server_cli_test.py",
"chars": 3027,
"preview": "\"\"\"Unit tests for API server CLI bootstrap helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport unittest\nfro"
},
{
"path": "acestep/api/server_utils.py",
"chars": 3782,
"preview": "\"\"\"Shared helper utilities used by API server request and runtime flows.\"\"\"\n\nfrom __future__ import annotations\n\nimport "
},
{
"path": "acestep/api/server_utils_test.py",
"chars": 3173,
"preview": "\"\"\"Unit tests for shared API server utility helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport unittest\nf"
},
{
"path": "acestep/api/startup_llm_init.py",
"chars": 4484,
"preview": "\"\"\"LLM startup initialization helper for API server.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing impor"
},
{
"path": "acestep/api/startup_llm_init_test.py",
"chars": 3478,
"preview": "\"\"\"Unit tests for LLM startup initialization helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport unittest\nf"
},
{
"path": "acestep/api/startup_model_init.py",
"chars": 7117,
"preview": "\"\"\"Startup model initialization orchestration for API server lifespan.\"\"\"\n\nfrom __future__ import annotations\n\nimport os"
},
{
"path": "acestep/api/startup_model_init_test.py",
"chars": 6210,
"preview": "\"\"\"Unit tests for startup model initialization orchestration helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\ni"
},
{
"path": "acestep/api/train_api_dataset_auto_label_async_route.py",
"chars": 9327,
"preview": "\"\"\"Async auto-label route registration for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimpo"
},
{
"path": "acestep/api/train_api_dataset_auto_label_routes.py",
"chars": 1772,
"preview": "\"\"\"Auto-label route-registration facade for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing i"
},
{
"path": "acestep/api/train_api_dataset_auto_label_routes_http_test.py",
"chars": 7172,
"preview": "\"\"\"HTTP integration tests for dataset auto-label route registration.\"\"\"\n\nfrom __future__ import annotations\n\nfrom contex"
},
{
"path": "acestep/api/train_api_dataset_auto_label_status_route.py",
"chars": 1638,
"preview": "\"\"\"Auto-label status-by-task route registration for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom "
},
{
"path": "acestep/api/train_api_dataset_auto_label_sync_route.py",
"chars": 5152,
"preview": "\"\"\"Sync auto-label route registration for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimpor"
},
{
"path": "acestep/api/train_api_dataset_models.py",
"chars": 5300,
"preview": "\"\"\"Request payload schemas and sample serialization for training dataset routes.\"\"\"\n\nfrom __future__ import annotations\n"
},
{
"path": "acestep/api/train_api_dataset_models_test.py",
"chars": 4483,
"preview": "\"\"\"Unit tests for training dataset request models and serialization helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimp"
},
{
"path": "acestep/api/train_api_dataset_preprocess_routes.py",
"chars": 7904,
"preview": "\"\"\"Preprocess route registration for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimpor"
},
{
"path": "acestep/api/train_api_dataset_preprocess_routes_http_test.py",
"chars": 4626,
"preview": "\"\"\"HTTP integration tests for dataset preprocess routes.\"\"\"\n\nfrom __future__ import annotations\n\nfrom types import Simpl"
},
{
"path": "acestep/api/train_api_dataset_sample_routes.py",
"chars": 4550,
"preview": "\"\"\"Sample and dataset-save route registration for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom ty"
},
{
"path": "acestep/api/train_api_dataset_sample_routes_http_test.py",
"chars": 5128,
"preview": "\"\"\"HTTP integration tests for dataset save/sample routes.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any"
},
{
"path": "acestep/api/train_api_dataset_scan_load_routes.py",
"chars": 3634,
"preview": "\"\"\"Scan/load dataset route registration for training APIs.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing"
},
{
"path": "acestep/api/train_api_dataset_scan_load_routes_http_test.py",
"chars": 6545,
"preview": "\"\"\"HTTP integration tests for dataset scan/load route registration.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing "
},
{
"path": "acestep/api/train_api_dataset_service.py",
"chars": 2044,
"preview": "\"\"\"Dataset-route registration facade for training APIs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, "
},
{
"path": "acestep/api/train_api_dataset_service_http_test.py",
"chars": 6962,
"preview": "\"\"\"HTTP integration tests for dataset route registration behavior.\"\"\"\n\nfrom __future__ import annotations\n\nfrom contextl"
},
{
"path": "acestep/api/train_api_dataset_status_routes.py",
"chars": 3794,
"preview": "\"\"\"Latest-status route registration for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing impor"
},
{
"path": "acestep/api/train_api_dataset_status_routes_http_test.py",
"chars": 4030,
"preview": "\"\"\"HTTP integration tests for latest-status dataset routes.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import A"
},
{
"path": "acestep/api/train_api_lokr_start_route.py",
"chars": 7569,
"preview": "\"\"\"LoKR training start route registration.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport re\nimport threading\n"
},
{
"path": "acestep/api/train_api_lora_start_route.py",
"chars": 6717,
"preview": "\"\"\"LoRA training start route registration.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport re\nimport threading\n"
},
{
"path": "acestep/api/train_api_models.py",
"chars": 5591,
"preview": "\"\"\"Request models and shared state helpers for training APIs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom dataclasses i"
},
{
"path": "acestep/api/train_api_runtime.py",
"chars": 6579,
"preview": "\"\"\"Runtime helpers for training API temporary component management.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing "
},
{
"path": "acestep/api/train_api_service.py",
"chars": 7977,
"preview": "\"\"\"Training API route registration facade.\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport os\nimport shutil\nf"
},
{
"path": "acestep/api/train_api_service_http_test.py",
"chars": 5215,
"preview": "\"\"\"HTTP integration tests for training API route registration.\"\"\"\n\nfrom __future__ import annotations\n\nfrom contextlib i"
},
{
"path": "acestep/api/worker_runtime.py",
"chars": 2564,
"preview": "\"\"\"Background worker task orchestration helpers for API server.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nf"
},
{
"path": "acestep/api/worker_runtime_test.py",
"chars": 2348,
"preview": "\"\"\"Unit tests for background worker task orchestration helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nim"
},
{
"path": "acestep/api_server.py",
"chars": 13368,
"preview": "\"\"\"FastAPI server for ACE-Step V1.5.\n\nEndpoints:\n- POST /release_task Create music generation task\n- POST /quer"
},
{
"path": "acestep/audio_utils.py",
"chars": 18339,
"preview": "\"\"\"\r\nAudio saving and transcoding utility module\r\n\r\nIndependent audio file operations outside of handler, supporting:\r\n-"
},
{
"path": "acestep/audio_utils_test.py",
"chars": 13788,
"preview": "\"\"\"Unit tests for audio_utils module, focusing on format support.\"\"\"\n\nimport os\nimport tempfile\nimport unittest\nfrom pat"
},
{
"path": "acestep/audio_utils_uuid_test.py",
"chars": 9714,
"preview": "\"\"\"Test UUID generation includes LoRA state to prevent file reuse.\"\"\"\nimport os\nimport tempfile\nimport unittest\n\nfrom ac"
},
{
"path": "acestep/cli_args.py",
"chars": 1059,
"preview": "\"\"\"Argument parsing helpers shared by ACE-Step CLI entrypoints.\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\n"
},
{
"path": "acestep/cli_args_test.py",
"chars": 1585,
"preview": "\"\"\"Unit tests for CLI argument parsing helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport unittest\n"
},
{
"path": "acestep/constants.py",
"chars": 8050,
"preview": "\"\"\"\nConstants for ACE-Step\nCentralized constants used across the codebase\n\"\"\"\n\n# ======================================="
},
{
"path": "acestep/constrained_logits_processor.py",
"chars": 114447,
"preview": "\n\"\"\"\nConstrained Logits Processor for ACE-Step Language Model\n\nThis module implements a finite state machine (FSM) based"
},
{
"path": "acestep/core/__init__.py",
"chars": 89,
"preview": "\"\"\"Core package intent: framework-agnostic domain logic for generation and inference.\"\"\"\n"
},
{
"path": "acestep/core/audio/__init__.py",
"chars": 80,
"preview": "\"\"\"Audio package intent: reusable audio IO, transforms, and codec utilities.\"\"\"\n"
},
{
"path": "acestep/core/generation/__init__.py",
"chars": 93,
"preview": "\"\"\"Generation package intent: music generation orchestration, params, and diffusion flow.\"\"\"\n"
},
{
"path": "acestep/core/generation/handler/__init__.py",
"chars": 2858,
"preview": "\"\"\"Handler decomposition components.\"\"\"\n\nfrom .audio_codes import AudioCodesMixin\nfrom .batch_prep import BatchPrepMixin"
},
{
"path": "acestep/core/generation/handler/audio_codes.py",
"chars": 4446,
"preview": "\"\"\"Audio-code parsing and conversion helpers for handler decomposition.\"\"\"\n\nimport re\nimport traceback\nfrom typing impor"
},
{
"path": "acestep/core/generation/handler/batch_prep.py",
"chars": 4266,
"preview": "\"\"\"Batch preparation helpers for handler decomposition.\"\"\"\n\nfrom typing import Dict, List, Optional, Union\n\nimport torch"
},
{
"path": "acestep/core/generation/handler/conditioning_batch.py",
"chars": 6388,
"preview": "\"\"\"Batch-conditioning orchestration helpers for handler decomposition.\"\"\"\n\nfrom typing import Any, Dict, List, Optional,"
},
{
"path": "acestep/core/generation/handler/conditioning_batch_test.py",
"chars": 6193,
"preview": "\"\"\"Unit tests for batch-conditioning orchestration mixin.\"\"\"\n\nimport unittest\nfrom typing import Any, Dict, List, Option"
},
{
"path": "acestep/core/generation/handler/conditioning_embed.py",
"chars": 6741,
"preview": "\"\"\"Reference/text embedding preprocessing helpers for conditioned generation.\"\"\"\n\nfrom typing import Dict, List, Tuple\n\n"
},
{
"path": "acestep/core/generation/handler/conditioning_embed_test.py",
"chars": 4702,
"preview": "\"\"\"Unit tests for conditioning embedding/preprocess mixin.\"\"\"\n\nfrom contextlib import contextmanager\nimport unittest\n\nim"
},
{
"path": "acestep/core/generation/handler/conditioning_masks.py",
"chars": 5354,
"preview": "\"\"\"Chunk-mask and source-latent helpers for batch conditioning.\"\"\"\n\nfrom typing import Dict, List, Optional, Tuple\n\nimpo"
},
{
"path": "acestep/core/generation/handler/conditioning_masks_test.py",
"chars": 10068,
"preview": "\"\"\"Unit tests for ConditioningMaskMixin chunk-mask and source-latent behavior.\"\"\"\n\nimport unittest\nfrom typing import Li"
},
{
"path": "acestep/core/generation/handler/conditioning_target.py",
"chars": 6134,
"preview": "\"\"\"Target-latent preparation helpers for handler batch conditioning.\"\"\"\n\nfrom typing import List, Optional, Tuple\n\nimpor"
},
{
"path": "acestep/core/generation/handler/conditioning_text.py",
"chars": 9162,
"preview": "\"\"\"Text-token and hint preparation helpers for batch conditioning.\"\"\"\n\nfrom typing import List, Optional, Tuple\n\nimport "
},
{
"path": "acestep/core/generation/handler/cover_noise_strength_forwarding_test.py",
"chars": 3374,
"preview": "\"\"\"Regression tests for cover-noise-strength forwarding in generation.\"\"\"\n\nimport contextlib\nimport types\nimport unittes"
},
{
"path": "acestep/core/generation/handler/diffusion.py",
"chars": 6373,
"preview": "\"\"\"Diffusion-related handler helpers.\"\"\"\n\nfrom typing import Any, Dict, Optional\n\nimport torch\nfrom acestep.models.mlx.d"
},
{
"path": "acestep/core/generation/handler/diffusion_test.py",
"chars": 6707,
"preview": "import unittest\nfrom unittest.mock import patch\n\nimport numpy as np\nimport torch\n\nfrom acestep.core.generation.handler.d"
},
{
"path": "acestep/core/generation/handler/generate_music.py",
"chars": 13860,
"preview": "\"\"\"Top-level ``generate_music`` orchestration mixin.\n\nThis module provides the public ``generate_music`` entry point ext"
},
{
"path": "acestep/core/generation/handler/generate_music_decode.py",
"chars": 9781,
"preview": "\"\"\"Decode/validation helpers for ``generate_music`` orchestration.\"\"\"\n\nimport gc\nimport os\nimport time\nfrom typing impor"
},
{
"path": "acestep/core/generation/handler/generate_music_decode_test.py",
"chars": 12102,
"preview": "\"\"\"Tests for extracted ``generate_music`` decode helper mixin behavior.\"\"\"\n\nimport importlib.util\nimport types\nimport sy"
},
{
"path": "acestep/core/generation/handler/generate_music_execute.py",
"chars": 5946,
"preview": "\"\"\"Execution helper for ``generate_music`` service invocation with progress tracking.\"\"\"\n\nimport os\nimport threading\nfro"
},
{
"path": "acestep/core/generation/handler/generate_music_execute_test.py",
"chars": 3128,
"preview": "\"\"\"Unit tests for ``generate_music`` execution helper mixin.\"\"\"\n\nimport unittest\n\nfrom acestep.core.generation.handler.g"
},
{
"path": "acestep/core/generation/handler/generate_music_payload.py",
"chars": 3903,
"preview": "\"\"\"Success payload builders for ``generate_music`` orchestration.\"\"\"\n\nfrom typing import Any, Dict\n\nfrom loguru import l"
},
{
"path": "acestep/core/generation/handler/generate_music_payload_test.py",
"chars": 7650,
"preview": "\"\"\"Tests for extracted ``generate_music`` success-payload builder behavior.\n\nThe module loads ``acestep.core.generation."
},
{
"path": "acestep/core/generation/handler/generate_music_request.py",
"chars": 8700,
"preview": "\"\"\"Input and preflight helpers for ``generate_music`` orchestration.\"\"\"\n\nfrom typing import Any, Callable, Dict, List, O"
},
{
"path": "acestep/core/generation/handler/generate_music_request_test.py",
"chars": 5606,
"preview": "\"\"\"Unit tests for ``generate_music`` request helper mixin.\"\"\"\n\nimport types\nimport unittest\n\nimport torch\n\nfrom acestep."
},
{
"path": "acestep/core/generation/handler/generate_music_test.py",
"chars": 10719,
"preview": "\"\"\"Tests for extracted ``generate_music`` orchestration behavior.\n\nThe module loads ``acestep.core.generation.handler.ge"
},
{
"path": "acestep/core/generation/handler/init_service.py",
"chars": 919,
"preview": "\"\"\"Facade mixin that composes initialization helper modules.\"\"\"\n\nfrom .init_service_catalog import InitServiceCatalogMix"
}
]
// ... and 948 more files (download for full content)
About this extraction
This page contains the full source code of the ace-step/ACE-Step-1.5 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1148 files (10.3 MB), approximately 2.8M tokens, and a symbol index with 3678 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.