| 2136 | }; |
| 2137 | |
| 2138 | struct llama_sampler * llama_sampler_init_dry(const struct llama_vocab * vocab, int32_t context_size, float dry_multiplier, float dry_base, int32_t dry_allowed_length, int32_t dry_penalty_last_n, const char** seq_breakers, size_t num_breakers) { |
| 2139 | int32_t effective_dry_penalty_last_n = (dry_penalty_last_n == -1) ? context_size : std::max(dry_penalty_last_n, 0); |
| 2140 | std::unordered_multimap<llama_token, std::vector<llama_token>> processed_breakers; |
| 2141 | const int MAX_CHAR_LEN = 40; |
| 2142 | const int MAX_SEQ_LEN = 20; |
| 2143 | |
| 2144 | const bool dry_enabled = (dry_multiplier != 0.0f && dry_base >= 1.0f && dry_penalty_last_n != 0); |
| 2145 | |
| 2146 | if (dry_enabled && seq_breakers != nullptr && num_breakers > 0) { |
| 2147 | // Process sequence breakers |
| 2148 | for (size_t i = 0; i < num_breakers; ++i) { |
| 2149 | if (seq_breakers[i] == nullptr || std::strlen(seq_breakers[i]) == 0) { |
| 2150 | LLAMA_LOG_WARN("skipping null or empty DRY sequence breaker at index %zu\n", i); |
| 2151 | continue; |
| 2152 | } |
| 2153 | |
| 2154 | std::string sequence_break(seq_breakers[i]); |
| 2155 | if (sequence_break.empty()) { |
| 2156 | LLAMA_LOG_WARN("skipping empty DRY sequence breaker\n"); |
| 2157 | continue; |
| 2158 | } |
| 2159 | |
| 2160 | if (sequence_break.size() > MAX_CHAR_LEN) { |
| 2161 | LLAMA_LOG_WARN("truncating DRY sequence breaker to %d characters\n", MAX_CHAR_LEN); |
| 2162 | sequence_break.resize(MAX_CHAR_LEN); |
| 2163 | } |
| 2164 | |
| 2165 | get_overlapping_token_sequences(*vocab, sequence_break, processed_breakers, MAX_SEQ_LEN); |
| 2166 | } |
| 2167 | } |
| 2168 | |
| 2169 | return llama_sampler_init( |
| 2170 | /* .iface = */ &llama_sampler_dry_i, |
| 2171 | /* .ctx = */ new llama_sampler_dry { |
| 2172 | /* .total_context_size = */ context_size, |
| 2173 | /* .dry_multiplier = */ dry_multiplier, |
| 2174 | /* .dry_base = */ dry_base, |
| 2175 | /* .dry_allowed_length = */ dry_allowed_length, |
| 2176 | /* .dry_penalty_last_n = */ dry_penalty_last_n, |
| 2177 | /* .dry_processed_breakers = */ std::move(processed_breakers), |
| 2178 | /* .dry_repeat_count = */ dry_enabled ? std::vector<int>(effective_dry_penalty_last_n, 0) : std::vector<int>{}, |
| 2179 | /* .dry_max_token_repeat = */ {}, |
| 2180 | /* .last_tokens = */ dry_enabled ? ring_buffer<llama_token>(effective_dry_penalty_last_n) : ring_buffer<llama_token>(0), |
| 2181 | } |
| 2182 | ); |
| 2183 | } |
| 2184 | |
| 2185 | // wrapper for test-sampling.cpp |
| 2186 | struct llama_sampler * llama_sampler_init_dry_testing(int32_t context_size, float dry_multiplier, float dry_base, int32_t dry_allowed_length, int32_t dry_penalty_last_n, const std::vector<std::vector<llama_token>>& seq_breakers) { |
no test coverage detected