Spaces:
Sleeping
Sleeping
Download solar_eval/pipelines/steps/completion.py from dev-strender/proofread-demo: direct link, hf CLI and curl.
- Browser
- Download file 3.74 kB
-
https://huggingface.co/spaces/dev-strender/proofread-demo/resolve/main/solar_eval/pipelines/steps/completion.py
- Command line
-
hf download hf://spaces/dev-strender/proofread-demo/solar_eval/pipelines/steps/completion.py
-
curl -L -o completion.py https://huggingface.co/spaces/dev-strender/proofread-demo/resolve/main/solar_eval/pipelines/steps/completion.py
3.74 kB
| """`llm_completion` μ€ν -- input_fields λ‘ μ μ λ©μμ§λ₯Ό λ§λ€μ΄ ν λ² νΈμΆ. | |
| `single_step.py`(SingleStepPipeline) μμ λ‘μ§ μ΄λ (2026-08-10, λμ λμΌ). | |
| λ²μ/μμ½μ²λΌ "μ λ ₯ νλλ€ β μμ±λ¬Έ νλ" ννμ νμ€ν¬κ° μ΄λ€. | |
| `pipeline: single_step` μ μΈμ μ΄ μ€ν νλμ§λ¦¬ νμ΄νλΌμΈμΌλ‘ ν΄μλλ€. | |
| """ | |
| import logging | |
| from typing import Any | |
| from solar_eval.models.sample import EvalSample | |
| from solar_eval.pipelines.pipeline import BaseStep, StepContext | |
| from solar_eval.pipelines.registry import register_step | |
| logger = logging.getLogger(__name__) | |
| class LLMCompletionStep(BaseStep): | |
| """Single LLM call step. Used for translation and summarization.""" | |
| async def run(self, sample: EvalSample, ctx: StepContext) -> None: | |
| input_data = self._input_fields_dict(sample.input) | |
| if ctx.messages: | |
| # Structured messages mode: substitute {{field}} placeholders | |
| resolved = self._resolve_messages(ctx.messages, input_data) | |
| else: | |
| # Legacy mode: system prompt + auto-built user message | |
| user_content = self._build_user_message(input_data) | |
| resolved = [ | |
| {"role": "system", "content": ctx.system_prompt}, | |
| {"role": "user", "content": user_content}, | |
| ] | |
| result = await ctx.provider.chat_completion( | |
| messages=resolved, | |
| model=self.config.get("model", ctx.model), | |
| temperature=self.config.get("temperature", ctx.temperature), | |
| max_tokens=self.config.get("max_tokens", ctx.max_tokens), | |
| reasoning_effort=self.config.get("reasoning_effort", ctx.reasoning_effort), | |
| ) | |
| ctx.text = result["content"] | |
| ctx.add_usage(result.get("usage", {})) | |
| sample.artifacts["think_content"] = result.get("think_content", "") | |
| sample.artifacts["finish_reason"] = result.get("finish_reason", "stop") | |
| def _input_fields_dict(self, sample_input: Any) -> dict[str, Any]: | |
| """`sample.input` μ {νλλͺ : κ°} dict λ‘ μ κ·ννλ€. | |
| λ¬λλ `task_config`μ `input_fields` μ μ²΄λ‘ λ§λ dict λ₯Ό κ·Έλλ‘ | |
| `sample.input` μ λ΄μ λκΈ΄λ€(λ¨μΌ νλλ λ€μ€ νλλ ). μ¬κΈ°μλ | |
| κ·Έ κ΄λ‘λ₯Ό κ·Έλλ‘ λ°λ, λ€λ₯Έ shape μ΄ λ€μ΄μ€λ©΄ μ‘°μ©ν 무μνμ§ μκ³ | |
| λ°λ‘ μ€ν¨μν¨λ€. | |
| """ | |
| if sample_input is None: | |
| return {} | |
| if isinstance(sample_input, dict): | |
| return sample_input | |
| raise TypeError( | |
| "LLMCompletionStep expects sample.input to be a dict of " | |
| f"{{field: value}} (runner.py convention); got {type(sample_input)}" | |
| ) | |
| def _resolve_messages( | |
| self, messages: list[dict[str, str]], input_data: dict[str, Any] | |
| ) -> list[dict[str, str]]: | |
| """Substitute {{field_name}} placeholders in message content.""" | |
| resolved = [] | |
| for msg in messages: | |
| content = msg["content"] | |
| for field, value in input_data.items(): | |
| content = content.replace(f"{{{{{field}}}}}", str(value)) | |
| resolved.append({"role": msg["role"], "content": content}) | |
| return resolved | |
| def _build_user_message(self, input_data: dict[str, Any]) -> str: | |
| input_fields = self.env.input_fields | |
| if len(input_fields) == 1: | |
| return str(input_data.get(input_fields[0], "")) | |
| # Multiple fields: format as labeled sections | |
| parts = [] | |
| for field in input_fields: | |
| value = input_data.get(field, "") | |
| parts.append(f"{field}:\n{value}") | |
| return "\n\n".join(parts) | |