Вспомогательные функции
Определение языка
laya.detect_language — это laya.lang.analyse.
Имена, типы, значения по умолчанию и код остаются на английском; остальное переведено (ещё не переведённые записи показываются в английском оригинале).
analyse
analyse(state: Union[str, bytes, Mapping, list, None]) -> Dict[str, object]Полный результат определения для состояния.
Возвращает script, script_profile, language (по мере возможности, может быть None),
is_english, non_latin_fraction и mixed_segment (строка или поле, которое сделало преимущественно
английское состояние неанглийским, иначе None).
Читаются именно строковые значения. Когда у состояния их несколько, достаточно одного неанглийского значения: объединение всех значений в одно окно позволяло длинной английской заметке заполнить 4000 символов или перевесовать короткое немецкое сообщение, и это сообщение затем отправлялось на английский чекпойнт (#384). Сканирование сегментов всё равно останавливается на 4000 символов, что и делает огромное поле дешёвым; значение, до которого оно не дошло, читается отдельно после этого.
Параметры
stateUnion[str, bytes, Mapping, list, None]
detect_script
detect_script(text: str) -> strДоминирующая письменность text: 'latin', 'han', 'devanagari', ... или 'unknown', если букв нет.
Параметры
textstr
is_english
is_english(state: Union[str, bytes, Mapping, list, None]) -> boolTrue, когда можно ожидать, что английский чекпойнт прочитает это состояние.
Параметры
stateUnion[str, bytes, Mapping, list, None]
Электронная почта
clean_email_body
clean_email_body(body: str, max_chars: int = 3000) -> strУдаляет цитируемую историю письма, подписи и дисклеймеры, чтобы держать вход сфокусированным.
max_chars — это длина, до которой обрезается результат, 3000 символов, если не увеличено -- см.
email_state, который принимает тот же бюджет и передаёт его дальше.
Параметры
bodystrmax_charsint=3000
email_state
email_state(
subject: str,
body: str,
sender: Optional[str] = None,
clean: bool = True,
max_chars: int = 3000,
extra,
) -> DictСтроит чистый словарь состояния для классификации почты.
max_chars — это бюджет, до которого clean_email_body обрезает тело, и его стоит увеличить для
длинного сообщения: при значении по умолчанию тело обрывается после 3000 символов, так что запрос, который приходит в
последних абзацах, никогда не доходит до модели -- в том числе через predict_long, который сканирует
состояние в окнах именно для того, чтобы читать дальше одного окна. Игнорируется при clean=False,
который пропускает тело целиком.
Любое другое именованное слово становится полем состояния, так что модель его читает; опечатка здесь — это мутация входа, а не ошибка.
Параметры
subjectstrbodystrsenderOptional[str]=Nonecleanbool=Truemax_charsint=3000extra
Пресеты вопросов
triage_questions
triage_questions() -> DictПредустановленные вопросы для триажа тикетов поддержки клиентов.
email_questions
email_questions(categories: Optional[Dict[str, str]] = None) -> DictПредустановленные вопросы для триажа входящей почты и фильтрации угроз.
Параметры
categoriesOptional[Dict[str, str]]=None
guard_questions
guard_questions() -> DictПредустановленные вопросы для ограничителей входа LLM в реальном времени.
moderation_questions
moderation_questions() -> DictПредустановленные вопросы для безопасности контента и модерации.
router_questions
router_questions() -> DictПредустановленные вопросы для интеллектуальной маршрутизации моделей.
Отбор кандидатов
shortlist_choice
shortlist_choice(
state: Any,
criteria: Any,
embed_fn: Callable[[Sequence[str]], Any],
k: int = DEFAULT_SHORTLIST_K,
DEFAULT_SHORTLIST_K,
instructions: Optional[str] = None,
return_scores: bool = False,
) -> AnyВозвращает top-k меток choice для state.
embed_fn сопоставляет список строк массиву формы (len(texts), dim).
Она вызывается один раз: сначала текст запроса, затем по одной строке на каждую опцию в
порядке criteria. Строки опций совпадают с render_options для вопроса choice.
Когда k не меньше числа меток, каждая метка возвращается в своём
исходном порядке, а embed_fn не вызывается.
Ничьи сохраняют более раннюю метку. Ранжирование — это знаковый косинус, а не порог схожести:
метка, набравшая 0 -- полное отсутствие сигнала или нефинитный вектор, обработанный как таковой,
-- всё же обгоняет более раннюю метку, набравшую отрицательное значение, а k отбрасывает
отрицательные метки первыми.
При return_scores=True возвращается пара (labels, scores), где
scores содержит знаковый косинус каждой сохранённой метки в порядке ранжирования -- те же
значения, которые predict_shortlist сообщает в своих метаданных shortlist. scores
равен None, когда ничего не было отброшено, в точности как в этих метаданных.
Параметры
stateAnycriteriaAnyembed_fnCallable[[Sequence[str]], Any]kint=DEFAULT_SHORTLIST_KDEFAULT_SHORTLIST_KinstructionsOptional[str]=Nonereturn_scoresbool=False
predict_shortlist
predict_shortlist(
agent: Any,
state: Any,
questions: Dict[str, Dict[str, Any]],
embed_fn: Callable[[Sequence[str]], Any],
k: int = DEFAULT_SHORTLIST_K,
DEFAULT_SHORTLIST_K,
predict_kwargs: Any,
) -> Dict[str, Any]Формирует шортлист для каждого вопроса choice, затем один раз вызывает predict или system_one.
Вопросы, не являющиеся choice, передаются без изменений. Choice, у которого число меток
<= k, передаётся без изменений и не вызывает embed_fn. Словарь
questions вызывающего не изменяется.
Возвращаемый словарь — это результат модели плюс запись shortlist. Вероятности
на сокращённом choice — только по сохранённым меткам. shortlist[qid] содержит
labels, scores, k, n и passthrough. labels — это порядок ранжирования,
который создал шортлист, или сам порядок criteria, когда passthrough задан
и ранжирование не выполнялось; scores — знаковый косинус каждой сохранённой метки в этом
порядке -- включая отрицательные, никогда не обрезается до 0 -- или None, когда ничего не было
отброшено.
Дополнительные именованные аргументы передаются в predict / system_one (например,
model= у Router).
Параметры
agentAnystateAnyquestionsDict[str, Dict[str, Any]]embed_fnCallable[[Sequence[str]], Any]kint=DEFAULT_SHORTLIST_KDEFAULT_SHORTLIST_Kpredict_kwargsAny
embed_fn_from_agent
embed_fn_from_agent(
agent: Any,
max_length: int = 512,
batch_size: int = 32,
) -> Callable[[Sequence[str]], np.ndarray]Усредняет (mean-pool) энкодер чекпойнта, уже загруженный на agent.
Вызываемый объект встраивает список строк с помощью agent.tok и agent.model.encoder.
Он не запускает голову принятия решений и не загружает веса. Выделенный
би-энкодер, переданный как embed_fn, обычно даёт лучший шортлист; этот помощник — для
вызывающих, у которых в памяти есть только чекпойнт Laya.
Позиции padding исключаются из среднего. Флаг train/eval энкодера
остаётся таким, каким его задал вызывающий (загруженный Agent уже в eval).
Каждый вызов использует текущий agent.device, в том числе после перехода на CPU.
Параметры
agentAnymax_lengthint=512batch_sizeint=32
cached_embed_fn
cached_embed_fn(
embed_fn: Callable[[Sequence[str]], Any],
maxsize: int = 4096,
) -> Callable[[Sequence[str]], np.ndarray]Кэширует вывод embed_fn по каждой входной строке в пределах границы LRU.
predict_shortlist встраивает запрос плюс текст каждой опции при каждом вызове. Когда
один и тот же набор опций попадает в шортлист при каждом запросе -- фиксированный список интентов или меток, как
в примере BANKING77 из README -- строки опций не меняются между вызовами,
но встраиваются заново каждый раз. Обёртка эмбеддера один раз::
embed_fn = cached_embed_fn(embed_fn_from_agent(agent))
оставляет первый вызов неизменным и сводит каждый повторный вызов к встраиванию только нового запроса.
Поиск — точное совпадение строк. Тексты, отсутствующие в кэше, дедуплицируются и
встраиваются за один вызов embed_fn, так что холодный кэш стоит того же числа
пакетных вызовов, что и необёрнутая функция. Строки хранятся как float32; кэш содержит
не более maxsize строк, а затем вытесняет запись, использованную реже всего, ограничивая
память примерно maxsize * dim * 4 байтами. Ничего не кэшируется, когда embed_fn
возбуждает исключение или возвращает неверную форму.
Обёртку безопасно разделять между потоками: блокировка покрывает только чтение и запись
кэша, но никогда — вызов встраивания. Возвращаемый вызываемый объект несёт cache_info() --
словарь с size, maxsize, hits и misses -- и cache_clear().
Очистите кэш, если модель или веса за embed_fn меняются.
Параметры
embed_fnCallable[[Sequence[str]], Any]maxsizeint=4096
Воздержание от ответа
check_min_confidence
check_min_confidence(v: Any)Проверяет opt-in порог отказа от ответа min_confidence (#361, #394).
Либо вещественное число в [0.0, 1.0] (один порог для каждого ответа; логические значения отклоняются,
хотя isinstance(True, int)), либо сопоставление по бакетам (см. :func:check_min_confidence_map),
так что порог может различаться по числу опций. Возвращает значение в его проверенной форме -- float
для скалярного случая, dict[str, float] для случая сопоставления -- которое принимают обе
функции gating ниже.
Параметры
vAny
check_min_confidence_map
check_min_confidence_map(m: Dict[Any, Any]) -> Dict[str, float]Проверяет карту порогов отказа от ответа по бакетам (#394).
Ключи — это строки бакетов по числу опций в написании common.temp_bucket -- "choice:2",
"choice:3-5", "score:6-10", "noul:2" и так далее -- плюс необязательный "default",
используемый для любого бакета, который карта не называет. Значения — вещественные числа в [0.0, 1.0]. Один порог
уверенности не переносится между числами опций (#394); это позволяет вызывающему фильтровать каждый бакет
на уровне, который фактически заслуживает его калибровка. Подберите её с помощью
:func:laya.calibrate.fit_abstention_thresholds.
Параметры
mDict[Any, Any]
resolve_min_confidence
resolve_min_confidence(
answer: Dict[str, Any],
thresholds: Dict[str, float],
default: float = 0.0,
) -> floatПорог, по которому фильтруется бакет числа опций этого ответа, в рамках карты по бакетам.
Сначала откатывается к записи "default" карты, затем к default (0.0 -- ничего не фильтровать), для
бакета, который карта не называет, так что ненастроенный бакет никогда не отказывается от ответа неожиданно.
Параметры
answerDict[str, Any]thresholdsDict[str, float]defaultfloat=0.0
flag_low_confidence
flag_low_confidence(results: List[Dict[str, Any]], min_confidence: float) -> NoneOpt-in маркер отказа от ответа (#361): помечает ответы, уверенность которых падает ниже min_confidence.
Читает answer_confidence (max(p), величина, которую описывают калибровочные числа и которая
не дрейфует с числом опций), с откатом на confidence, если
answer_confidence отсутствует.
Сырой ответ и уверенность остаются нетронутыми; low_confidence: True добавляется, когда ответ
падает ниже порога, и удаляется, если ранее помеченный ответ теперь его превышает (например,
когда словарь результата переиспользуется или переоценивается с другим порогом).
min_confidence — либо float (один порог для каждого ответа), либо сопоставление по бакетам
(#394), и тогда каждый ответ фильтруется по порогу своего бакета числа опций через
:func:resolve_min_confidence.
Параметры
resultsList[Dict[str, Any]]min_confidencefloat
apply_confidence_gate
apply_confidence_gate(
results: List[Dict[str, Any]],
min_confidence: Optional[float] = None,
) -> NoneСообщает состояние gating по уверенности для ответов, к которым gating действительно применялся.
Gating — это политика, а политика, применение которой нельзя наблюдать, не является таковой. Когда
min_confidence задан, это записывает abstention -- одно из :data:GATE_STATES -- в каждый
ответ, плюс abstention_threshold, чтобы вызывающий мог ответить на три вопроса, на которые иначе
не может:
- какая доля решений отказалась от ответа, вместо того чтобы выводить это из того,
была ли случайно выставлена
low_confidence; - на скольких ответах gating не смог определить решение, что логическое значение вообще не может выразить;
- какой порог дал эти результаты --
flag_low_confidenceпотребляет порог и отбрасывает его, так что без этого пакетный прогон с порогами по классам нельзя переразбить.
GATE_UNEVALUATED -- это случай, который логическое значение не может выразить: gating сработал, а ответ
не несёт пригодной уверенности, так что gating не смог решить. Сообщить об этом как о прохождении -- та же ложь,
что и сообщить об этом как о флаге.
Когда min_confidence не задан, это не записывает ничего. Ни abstention, ни
abstention_threshold, ни флага. В этом весь контракт: вызов без gating возвращает ровно
ту же полезную нагрузку, что и раньше, и наличие поля -- не четвёртое значение, прочитанное
из него -- говорит вызывающему, что gating сработал. Вызывайте его безусловно, один раз за вызов, вместо
проверки if min_confidence is not None:: именно эта проверка оставляет путь, сообщающий
вообще ничего, -- состояние, которое эта функция и призвана отличать.
Сам флаг остаётся за :func:flag_low_confidence -- это делегирует, а не
переписывает правило заново, так что логическое значение и сообщаемое состояние не могут разойтись.
min_confidence, равный ровно 0.0, был задан, поэтому состояния сообщаются, а
:func:flag_low_confidence трактует 0.0 как пустую операцию, ведь ничто не может упасть ниже него. Каждый
ответ, несущий пригодную уверенность, поэтому читается как passed, и именно эхо порога
отличает это от настоящего прохождения при настоящем пороге.
Параметры
resultsList[Dict[str, Any]]min_confidenceOptional[float]=None
GATE_STATES
GATE_STATES = (GATE_PASSED, GATE_ABSTAINED, GATE_UNEVALUATED)Калибровка и обучение
answer_confidence
answer_confidence(p: np.ndarray, k: int) -> floatМасса вероятности на сообщаемом ответе: max(p).
Это величина, которую подгоняет температурное масштабирование, и величина, по которой вычисляется
каждое калибровочное число в этом репозитории -- оба стенда бенчмарков берут conf = max(probs) перед
вызовом ece_score. Раздел README про gating опирается на сопутствующее свойство:
из ответов, возвращённых с уверенностью c, примерно c верны. Это свойство
условно, и условие по умолчанию не выполняется -- оно сохраняется только после того, как температуры
подобраны и проверены на отложенных данных для этого чекпойнта и этого числа опций.
Поставляемые чекпойнты сверхуверены: choice:11+ — заостритель ~10x, возвращающий
точечную массу в 1.0, так что порог, применённый к ним, отбирает ниже точности модели (issue #394).
confidence_from_probs ниже сообщает другую величину в другом масштабе и не несёт
такой гарантии, поэтому их нельзя сравнивать с одним и тем же порогом.
Параметры
pnp.ndarraykint
confidence_from_probs
confidence_from_probs(p: np.ndarray, k: int) -> floatУверенность по нормированной энтропии Шеннона: 1 - H(p) / log(k).
Насколько сконцентрировано всё распределение. Полезно, но не калибровано: это не то, что
подгоняет температурное масштабирование, и не то, что измеряет сообщаемый ECE. См. answer_confidence.
Параметры
pnp.ndarraykint
ece_score
ece_score(conf: np.ndarray, correct: np.ndarray, bins: int = 15) -> floatОжидаемая ошибка калибровки (ECE) по бинам уверенности.
Параметры
confnp.ndarraycorrectnp.ndarraybinsint=15
fit_temperatures
fit_temperatures = fit_temperature_mapfit_one_temperature
fit_one_temperature(pairs: Sequence, min_n: Optional[int] = None) -> floatПодбирает один скаляр T методом NLL + LBFGS по log T.
Результат — это clamp_temperature оптимизированного масштаба, так что он лежит в
[TEMP_MIN, TEMP_MAX] (или равен нейтральному 1.0, когда значение не является числом).
Возвращает 1.0, когда задано меньше min_n пар. min_n по умолчанию равен
MIN_BUCKET_N (нижний порог на бакет). Подгонки на уровне типа передают MIN_TYPE_N, который
ниже, так что набор данных, не заполняющий ни один бакет, всё равно получает скаляр, а не
остаётся на 1.0.
Параметры
pairsSequencemin_nOptional[int]=None
fit_temperature_map
fit_temperature_map(
records: Iterable,
compute_ece: bool = False,
seed: int = 0,
) -> Dict[str, Any]Подбирает скаляры на уровне типа и температуры по бакетам.
MIN_BUCKET_N — это нижний порог на бакет: меньшие бакеты исключаются из
temperature_by_options, и их покрывает скаляр на уровне типа. MIN_TYPE_N — это
отдельный, более низкий порог только для этого скаляра.
compute_ece=False (значение по умолчанию и путь, который сохраняет Agent.fit_temperatures)
подгоняется по всем записям и не возвращает ключ report. seed на этом пути игнорируется.
compute_ece=True откладывает ECE_HOLDOUT_FRAC каждого бакета, стратифицированно по
temp_bucket, используя seed, чтобы одни и те же записи всегда делились одинаково. Температуры
подбираются только по остатку, а ECE оценивается только по отложенным записям.
report["n"] — число поданных записей; report["n_eval"] — отложенное
число, на которое опирается ECE. Бакет, который после отложения упал бы ниже MIN_BUCKET_N,
подгоняется по всем своим записям, исключается из набора оценки и указывается в
report["buckets_excluded_from_eval"] вместо отбрасывания. n_by_bucket
всегда считает весь вход, в том числе когда сама подгонка использовала подмножество.
Параметры
recordsIterablecompute_ecebool=Falseseedint=0
fit_abstention_thresholds
fit_abstention_thresholds(
records: Iterable,
temperature: Sequence[float],
temperature_by_options: Dict[str, float],
binning_map: Optional[Dict[str, Dict[str, Any]]] = None,
target_error: float = 0.10,
min_bucket_n: int = MIN_ABSTAIN_BUCKET_N,
MIN_ABSTAIN_BUCKET_N,
conservative: bool = True,
) -> Dict[str, float]Подбирает порог отказа от ответа по temp_bucket, чтобы gating удерживал целевой уровень ошибки в каждом бакете.
Один min_confidence не переносится между числами опций (#394): калиброванная
уверенность ответа с 2 опциями и с 12 опциями живёт в разных масштабах, так что один порог отсекает слишком много
или слишком мало в зависимости от вопроса. Вместо этого здесь подбирается один порог на бакет, с ключами в точности
как у temperature_by_options (common.temp_bucket, например "choice:3-5"), и результат — это
карта min_confidence, которую :func:laya.confidence.check_min_confidence /
:func:laya.confidence.apply_confidence_gate принимают напрямую.
records — это те же кортежи (qtype, logits, target[, k]), что потребляет fit_temperature_map
(records_from_labeled строит их). Уверенность — это калиброванный max(p) -- логиты
сначала масштабируются подобранными temperature / temperature_by_options, так что пороги и
числа, которые сообщает runtime, находятся в одном масштабе. target_error — это допускаемая ошибка среди
принятых ответов; min_bucket_n опускает бакеты, слишком малые для подгонки, а conservative добавляет
запас в одну выборку. Пороги — это эмпирические срезы по калибровочному набору, а не формальная
гарантия покрытия -- проверяйте на отложенных данных (fit_temperature_map(..., compute_ece=True)
даёт отложенное разбиение) для gating в продакшене.
Передавайте binning_map, когда у агента, который будет обслуживать эти пороги, он установлен -- через
Agent.fit_binning или через калибровочную полезную нагрузку, которая несёт binning_map -- потому что
runtime перекалибровывает answer_confidence через эту карту, прежде чем что-либо её прочитает, так что срез,
подобранный без неё, — это срез в масштабе, которого gating никогда не видит. Тогда пороги оказываются в
бинаризованном масштабе, и порядок, в котором подбирались эти двое, перестаёт иметь значение. Измерено на 1,200
синтетических записях с 12 опциями при target_error=0.10: срез, подобранный без карты, удерживает 9.8%
ошибки при 50% покрытия на небинаризованных уверенностях, а при сравнении того же числа с бинаризованными
пропускает 94.5% ответов при 25.6% ошибки.
Параметры
recordsIterabletemperatureSequence[float]temperature_by_optionsDict[str, float]binning_mapOptional[Dict[str, Dict[str, Any]]]=Nonetarget_errorfloat=0.10min_bucket_nint=MIN_ABSTAIN_BUCKET_NMIN_ABSTAIN_BUCKET_Nconservativebool=True
fit_binning_map
fit_binning_map(
records: Iterable,
temperature: Sequence[float],
temperature_by_options: Dict[str, float],
bins: int = 15,
min_bucket_n: int = MIN_BINNING_BUCKET_N,
MIN_BINNING_BUCKET_N,
) -> Dict[str, Dict[str, Any]]Подбирает карту перекалибровки гистограммной бинаризации по temp_bucket для answer_confidence.
Температурное масштабирование применяет один скаляр на бакет; оно не может исправить бакет, у которого
кривая надёжности не является простым заострением/сглаживанием (патологический choice:11+, который несёт
поставляемый английский чекпойнт, — один из таких). Гистограммная бинаризация — это непараметрическая
альтернатива: разделите калиброванные уверенности бакета на bins бинов равной ширины в [0, 1] и отобразите
каждую уверенность, попадающую в бин, в эмпирическую точность этого бина. Она не требует предположения о
монотонности и лишних зависимостей (только NumPy; изотоническая регрессия потребовала бы scikit-learn).
records — это те же кортежи (qtype, logits, target[, k]), что потребляет fit_temperature_map;
уверенность — это калиброванный max(p) (логиты сначала масштабируются подобранными temperature /
temperature_by_options), так что карта бинаризации компонуется поверх карты температур, а не
заменяет её. Возвращает {bucket: {"bins": N, "values": [recalibrated confidence per bin]}};
бакеты ниже min_bucket_n опускаются. Примените её с помощью :func:apply_binning_map. Пустой бин
(диапазон уверенности, который калибровочный набор никогда не выдавал) отображается в свою собственную середину, то есть оставляет
эту область без изменений, так что невиданное значение никогда не перекалибровывается в выдуманный 0.
Параметры
recordsIterabletemperatureSequence[float]temperature_by_optionsDict[str, float]binsint=15min_bucket_nint=MIN_BINNING_BUCKET_NMIN_BINNING_BUCKET_N
apply_binning_map
apply_binning_map(
confidence: float,
bucket: str,
binning_map: Dict[str, Dict[str, Any]],
) -> floatПерекалибровывает один answer_confidence для его bucket по числу опций (common.temp_bucket).
Возвращает уверенность без изменений, когда в карте нет записи для бакета, так что бакет, для которого карта не подбиралась, проходит насквозь, а не приводится к неверному значению.
Параметры
confidencefloatbucketstrbinning_mapDict[str, Dict[str, Any]]
fit_binning
fit_binning(
records,
min_bucket_n: int = MIN_BINNING_BUCKET_N,
MIN_BINNING_BUCKET_N,
) -> Dict[str, Any]Подбирает карту гистограммной бинаризации поверх подобранных температур этого агента и сохраняет её.
records — это те же кортежи (qtype, logits, target[, k]), что потребляет fit_temperatures.
Ключи карты в точности как у temperature_by_options, она компонуется поверх
текущих температур и записывается save_calibration как binning_map.
Параметры
recordsmin_bucket_nint=MIN_BINNING_BUCKET_NMIN_BINNING_BUCKET_N
render_options
render_options(q: Dict) -> List[str]Отрисовывает тексты опций в порядке индексов меток. Семантический порядок Noul всегда [false, true].
Параметры
qDict
proper_reward
proper_reward(
q: torch.Tensor,
target: torch.Tensor,
qtype: torch.Tensor,
mask: torch.Tensor,
w_sph: float = 0.5,
w_rps: float = 1.0,
log_floor: float = -9.21,
) -> torch.TensorВознаграждение по строго собственному (proper) правилу оценки: log score + spherical score + ranked probability score.
q: [..., N, K] сообщаемые распределения target: [N, K] (one-hot или мягкие целевые распределения)
Параметры
qtorch.Tensortargettorch.Tensorqtypetorch.Tensormasktorch.Tensorw_sphfloat=0.5w_rpsfloat=1.0log_floorfloat=-9.21
td_lambda_targets
td_lambda_targets(p_true: torch.Tensor, batch: Dict, lam: float = 1.0) -> torch.TensorЦели TD(lambda) для траекторий многоходовых разговоров.
Параметры
p_truetorch.TensorbatchDictlamfloat=1.0
QTYPES
QTYPES = {"choice": 0, "score": 1, "noul": 2}QTYPE_NAMES
QTYPE_NAMES = {v: k for k, v in QTYPES.items()}