Conversation
|
I see you are excited about this PR. Can you confirm that it does what you expect it to do? Oh, there is also @Ph0rk0z who seemed excited about string bans elsewhere. |
|
So in case if one would add the strings such as: Will it coerce the LLM to be more permissive? [EDIT]: updated banned list: lol its working |
|
No, it does not work right. Looks like the tokens are permanently banned in all of the context. The point of my implementation was that the token is temporarily banned only on that specific spot, not anywhere later. So, it cannot "send shivers", but it can "send emails" later in the context. Please copy my implementation properly instead of trying to reinvent the bicycle. |
For non thinking models, you don't really need to do this, just prefill a few words, this paper still holds from the models I've used. Thinking models though, are a different beast where string banning could definitely be helpful, but I've seen them occasionally weasel into thinking about safety using obscure tokens. But again not that hard to steer against. Either way, ideally you'd be able to unban the strings later.
Lol, this message was sent as I was typing this. I've never used string ban, so no idea how it is implemented in other implementations, but I agree with this philosophy in general, there is a reason I only turn on DRY or other repeat penalizers until when the model is actually looping. Edit:
This sounds like there is a toggle mechanism. It might need frontend support as again no clue how this is used in any frontend as I've never used it. |
|
If it bans all the tokens, that's gonna end up being bad. A piece of the string might be required for some other word or phrase. Turning on penalties in the middle of a chat sounds annoying, let alone dry having to catch up unless started really high. banned_strings format should also match kobold/llama.cpp so that client implementations can be re-used. Otherwise everyone will have to patch their own front ends who often don't know to differentiate. My impressions is that they won't make a carve out. Not only silly, but everyone else, and you'll be stuck with a fixed text file you can't turn off/edit per request. |
|
What's should the format of the ban strings be? I never used any of them and it seems Silly tavern's implentation is broken. |
I'm mainly eager for an antislop controllable from ST, which I use as my chat GUI. Beside that, I defer to the observations already made on the respective approaches of each PR and.. on the apparent abruptness of the superseding. Note: sorry for the relative impertinence of my comment. |
|
In silly it just sends the strings inside banned_strings parameter with each request. I mainly used it on tabby because mainline didn't have a proper implementation. I think request logic is the same: |
|
@Ph0rk0z The format should be the same. Is it not? I only added Fix a bug where token bans are not removed right away. |
Does the latest version of this PR address your concern? |
There is still something fucky about it: My PR, no "banned_strings": My PR, "banned_strings": [", her eyes"] Your PR, no "banned_strings": Your PR, "banned_strings": [", her eyes"],"banned-n":1, As you can see, it for some reason repeats " town", which is not the intended behavior. That must be a coincidence, right? WRONG! Different prompt: My PR, no "banned_strings": My PR, "banned_strings": ["His eyes"] Your PR, no "banned_strings": Your PR, "banned_strings": ["His eyes"],"banned-n":1, PLEASE JUST COPY WHAT I DID! I HAD IT STRESS TESTED! STOP REINVENTING THE BICYCLE WITH SQUARE WHEELS! I have even more concerns:
|
|
I can check what's wrong. @SneedwareInc If you prefer your own implementation, the first thing you do is to resolve the conflicts in your PR with the main branch. Then make this feature inside a function with a simple flag for on and off like below: In its current status, it's by no way maintainable. What's better is if you can tell me how I should change my code instead of asking me to rewrite everything. |
|
@firecoperana I can resolve the conflicts, but please be more specific, explain to me what I need to do to make it maintainable as if I am a 7B model from 2023. |
|
I've no idea what a 7B model from 2023 be like, but I would hope it will be something like this: |
https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.1 |
|
Found the bug. @SneedwareInc The response should match yours. {"banned_strings": ["I can","I could","a helpful assistant"],"banned_n":1} It has the tendency to skip "I" and answer with "can". I also see more occurrence of the ban strings, so using -1 should make the performance a little better. |
|
@firecoperana I can see it backfiring and banning more than it should, there is a reason why kobold and I are using only first token ban. Keep it as an option, but set "banned_n":1 as default so no unexpected behavior occurs. I found another discrepancy: "n_predict": 100, Yours(83 tokens): Yours is not keeping the token count like mine. |
8bb26c4 to
c96ad27
Compare
|
I was using chat completions and didn't let it finish. Basically each has its own use case, but at least here you have an option to test what works best for you. Changed the default to 1. |
|
Do you have an agreement how to proceed? As @firecoperana stated, if you prefer your PR, please resolve merge conflicts and change as suggested in this comment. I think even LlaMA-1-7B can understand what is being suggested, Mistral-7B-Instruct-v01 is much too advanced already. |
|
@ikawrakow For now, no clear agreement. Mine is messy, but well-tested and includes a regex ban. As you can read in this thread, firecoperana's is very raw, and I would not be surprised if there are even more things broken here. I would strongly prefer mine; I can do a rewrite to make it compatible once I get my free daily requests. |
|
I don't mind waiting for it. @SneedwareInc I noticed that regex ban is not in koboldcpp yet, which says something about this feature. |
LostRuins/koboldcpp#1233 |
|
To clarify, this PR is not a direct port of koboldcpp's antislop feature, so it may behave similarly to or differently from koboldcpp. Just test the PR as it is and share your feedback. As the title suggests, it's only a string ban and not a regex ban. For regex ban, submit a feature request later. |
|
This would be a great feature to have, but did not work for me. For example, while testing with K2 Thinking, I used this command to run the model: Content of the ban list: And yet, the model still starts thinking with "The user". Using grammar in the mainline works, but I could not get that working in ik_llama.cpp either due to another issue: #116. I also tried with Having string-based bans would be great, so if anyone can suggest how to make this feature work, please share. |
|
Upon further testing, I also noticed that this PR makes the K2 Thinking model going in loops even when trying to answer a simple question like "Write a Python script to print first N prime numbers." - in its thoughts, the model keeps complaining it made typo or something is wrong, and trying again and again, in the "think" block I see complains like @ikawrakow |
Is this with the string ban? Does setting banned_bias to -9999 make your ban work? |
|
Yes, it was with the simple ban list: I tried regenerating few times for the same question, and each time the model went into looping in its thoughts complaining it cannot type what it wants (while still typing both "The user" and "the user" a lot). I intent to do more testing with both patches tomorrow. I will test banned_bias set to -9999 with this patch also. I think string banning is very powerful feature to have, but it needs not affect normal output that does not match the ban list, and currently both patches do affect normal output in one way or another for some reason. This kind of feature is what I missed for a long time, so I am very interested to test thoroughly and report back anything that may be of help to debug issues I have found so far. What I know for sure, the issues I mentioned are not caused by banning tokens that I intent to ban - for example using grammar to block "The user" (only got grammar-based banning working on mainline llama.cpp though) or even simpler -l option to set -100 bias to a specific tokens like " user" works just fine (both in ik_llama.cpp and mainline llama.cpp), and quality of the model remains good. |
|
I just increased the times we try to regenerate. Build with debug so you can see whether the ban string is detected. |
Actually, I get decent results with logit bias, for example: This is sufficient to make the model not to type "the user" everywhere. But obviously this does not really work for longer strings where the first token pushed the model the wrong way, like "sending shivers" or some unwanted patterns in programming - if the model types very "sloppy" string, it is more likely to produce even more slop afterwards. Hence why string banning would be very useful, making the model to type something else and remove annoying string that are not as easy to get rid of use "the user". By the way, in the mainline llama.cpp logit bias has no affect (neither I rested this patch once more. It had no effect at all in terms of banning intended strings. I tested with both K2 Thinking and K2.5, both begin every message with "The user...." even though I have ban list containing "The user" line. I did not notice any debug output. Using the I also no longer can reproduce the looping thoughts bug, but since then I also updated ik_llama.cpp. So the only issue remains it does not actually ban the string. My previous tests were just inside the thinking block, but this time I asked the model to repeat these two strings: Its thoughts were full of "the user" and it was able successfully output both strings after the code block.
I tried, but it did not work, I get "error: unknown argument". That said, if it were working, then -12 or lower bias would already produced very noticeable effect - the model at this point almost type the banned tokens, and will fail to repeat the test code block I shown above. At -100 the model cannot type the token at all. But the patch as far as I understand sets it to -999 by default, which in theory should be even stronger than -12 or -100. So, logit bias strength is not the issue here. Like I mentioned above, I did not notice any debug output after applying this patch. It just does not have any effect unfortunately, even outside of the "think" block. So my guess it just fails to find a match. I am not really sure how to debug this further. Maybe it is possible to add per token debug output? Something like --verbose but specific to this patch, showing what array of banned tokens it is comparing against, etc. |
3e5795a to
4f3f1be
Compare
|
@firecoperana I have been testing this patch for some time, and so far so good. Tool calling works, thinking works, chat completion works. It also seems to be superior to individual token banning. For example, if I ban using Model no longer starting thinking almost every message with "The", which increases variety, and it still can write something like "...but when a user..." - which it only does when actually relevant (like when I myself bring up discussion about users having issues on a website and we need to fix this and that). Also, K2.5 creativity seems to be improved after I applied this ban list. "The user" is something that triggers model to go into slop mode - if it types "the user", it is like a trigger to go into overtrained patterns, to the point it starts ignoring instructions (for this reason, it is of no use asking it not to use "the user" - if asked for that, it will be the first thing it will do). Once "the user" is gone however, it seems to listen better to what style to use, how to think, etc... maybe not entirely perfect, but much better. The result can obviously can be enhanced further by banning other unwanted phrases that are associated with slop. This is actually useful not only in creative writing but in programming too, to ban certain overtrained patterns. The main point is that having simple ban list as normal text is much easier to edit and maintain. I checked with many other phrases, including longer ones like Limitation is that some slop like "this isn't X, it is Y" (and other phrases that have arbitrary words in the middle) can't be banned easily without regex but I think it can be a separate feature to consider and out of scope of this patch. Literal strings already cover a lot of use cases. I tested this patch with different frontends and frameworks, including Roo Code (with native tool calling, SillyTavern, builtin web UI of llama-server. I also took another look at #1131 - it has more features but breaks tool calling and thinking, and looking at the code, my impression it would take major refactoring to fix it, at least I wasn't able to find a quick fix. Hence why my opinion this patch here is a better starting point, since it is simpler; and potentially more features can be considered to be added later if needed. But that's just my opinion, I am not very familiar with ik_llama.cpp code base yet. Overall, I think @firecoperana did an excellent job here, it is a feature I wanted for very long time! As of the token-based grammar feature from #1220, it is definitely useful too, to target token based patterns and has its own advantages - I can force the model to use a certain patterns, for example, or add something at the beginning of |
This reverts commit 8d952ff.
This reverts commit c46b781.
This PR implements the string ban function for all completions. A buffer is created where tokens are temporarily stored, checked against blacklist and then if a banned string is generated, tokens are temporarily banned and rewind the generation. The comparison is case insensitive. It will continue trying that until it generates good text. Good text is streamed out of the buffer.
To specify a ban list, either use
--banned-string-fileto pass the path to the file of the ban string list, where there is only one phrase per line, or usebanned_stringsin the payload.To ban a token, the logit_bias is set to -999. If you want to adjust use, set in
banned_biasin the payload."banned-n": n to set how many tokens to ban in the phrase when a match is found. By default it only bans the first token, but it could make the output less coherent during greedy sampling. To ban all tokens, pass
--banned-n -1in the parameter or use"banned-n:-1"in the payload.